【问题标题】:Type guard on conditional parameter type条件参数类型的类型保护
【发布时间】:2020-06-03 12:50:47
【问题描述】:

为什么这段代码不起作用?

Typescript 很容易猜到 (T extends '1' ? '1' : never) 类型的变量永远不会是 false,因此 NonFalse<TypeWithCondition<T>>true | (T extends '1' ? '1' : never) 完全相同。

这是一个打字稿错误吗?是否应该作为功能请求发布?

type TypeWithCondition<T> = boolean | (T extends '1' ? '1' : never);

type NonFalse<T> = Exclude<T, false>;

const logNonFalse = <T>(b: NonFalse<TypeWithCondition<T>>) => {
    console.log(b);
};

const test1 = <T>(a: TypeWithCondition<T>) => {
    if (a === false) throw new Error("Can't be false");
    logNonFalse(a);
    // Error : Argument of type 'true | ([T] extends ["1"] ? "1" : never)' is not assignable to parameter of type 'true'.
    //  Type '[T] extends ["1"] ? "1" : never' is not assignable to type 'true'.
    //    Type '"1"' is not assignable to type 'true'.(2345)
};

【问题讨论】:

  • test1 中的 T 被推断为 unknown,因为不清楚哪些值可以作为该泛型的输入。你能澄清一下这个函数允许的输入值是什么,或者扩展你试图用条件类型测试的内容吗?
  • @JacobGillespie 感谢您的评论。是的,Typescript 猜不出T 是什么,但这没关系。它可以是任何东西。我想要做的是在通用条件类型(TypeWithCondition&lt;T&gt; = boolean | (T extends '1' ? '1' : never) 此处)的“子类型”(TypeWithCondition&lt;T&gt; 此处不带 false)上调用函数(此处为 logNonFalse)。
  • 因为unknown 可以是任何东西,这会导致这里出现一些问题——这个例子中的一些Ts 与其他Ts 不同,所以它不能正确推断出什么是允许。我了解您想使用泛型调用 logNonFalse,但尚不清楚泛型代表什么。您希望允许哪些值作为logNonFalse 的输入?除了假的还有什么? T extends "1"... 代表什么?
  • 但是无论T 是什么,我们都应该拥有true | (T extends '1' ? '1' : never) extends NonFalse&lt;TypeWithCondition&lt;T&gt;&gt;'. For logNonFalse` 我想要任何不等于false 的东西。 T extends "1"... 只是条件类型的一个简单案例(我想实现一些更复杂的东西,我已经简化为这个例子)。
  • 如果您只是想阻止将false 传递给logNonFalse,您可以通过从NonFalse 中删除TypeWithCondition 来做到这一点:Playground Link。否则,对于更复杂的情况,请随时为您的问题添加更多细节。

标签: typescript generic-type-argument conditional-types


【解决方案1】:

Typescript 还不能处理这个问题。参见https://github.com/microsoft/TypeScript/issues/38863

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-09-28
    • 2022-01-26
    • 2020-06-27
    • 2022-10-13
    • 1970-01-01
    • 2021-09-12
    相关资源
    最近更新 更多