【发布时间】: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<T> = boolean | (T extends '1' ? '1' : never)此处)的“子类型”(TypeWithCondition<T>此处不带false)上调用函数(此处为logNonFalse)。 -
因为
unknown可以是任何东西,这会导致这里出现一些问题——这个例子中的一些Ts 与其他Ts 不同,所以它不能正确推断出什么是允许。我了解您想使用泛型调用 logNonFalse,但尚不清楚泛型代表什么。您希望允许哪些值作为logNonFalse的输入?除了假的还有什么?T extends "1"...代表什么? -
但是无论
T是什么,我们都应该拥有true | (T extends '1' ? '1' : never) extends NonFalse<TypeWithCondition<T>>'. ForlogNonFalse` 我想要任何不等于false 的东西。T extends "1"...只是条件类型的一个简单案例(我想实现一些更复杂的东西,我已经简化为这个例子)。 -
如果您只是想阻止将
false传递给logNonFalse,您可以通过从NonFalse中删除TypeWithCondition来做到这一点:Playground Link。否则,对于更复杂的情况,请随时为您的问题添加更多细节。
标签: typescript generic-type-argument conditional-types