为什么TS中的泛型接口不能正确推断类型? [英] Why can't the generic interface in TS infer the type correctly?
本文介绍了为什么TS中的泛型接口不能正确推断类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
一旦在泛型接口中使用了Explicit_value
扩展Explicit_value
,即使代码是100%正确的,TS的类型系统也会变得愚蠢。
function fn<T extends "a" | "b">(param: T): T {
if (param === "a") return "a"/* <-- error
Type '"a"' is not assignable to type 'T'.
'"a"' is assignable to the constraint of type 'T',
but 'T' could be instantiated with a different subtype of constraint '"a" | "b"'.
*/
else return "b"/* <-- error
Type '"b"' is not assignable to type 'T'.
'"b"' is assignable to the constraint of type 'T',
but 'T' could be instantiated with a different subtype of constraint '"a" | "b"'.
*/
}
//that's ok:
function fn2<T extends string>(param: T): T {
return param
}
//even this:
function fn3<T extends "a">(): T {
return "a"/* <-- error
Type '"a"' is not assignable to type 'T'.
'"a"' is assignable to the constraint of type 'T',
but 'T' could be instantiated with a different subtype of constraint '"a"'.
*/
}
推荐答案
我不会说它很愚蠢。它只是很安全。 请考虑以下示例:
function fn3<T extends "a">(): T {
return "a" // error
}
const result = fn3<'a' & { tag: 2 }>().tag // 2
表示T
扩展了a
,但不等于‘a’。
在上面示例中,result
是2
,但在运行时它等于undefined
。
这就是为什么TS会给您一个错误。泛型参数应与运行时值绑定。就像您在第二个示例中所做的那样。
让我们看看您的第一个示例:
function fn<T extends "a" | "b">(param: T): T {
if (param === "a") return "a"
else return "b"
}
错误:
请记住,这并不意味着"";a";"可赋给类型为"T"的约束,但"T"可以用约束"";a";|";b";""的不同子类型实例化。
T
总是等于a
或b
。T
可以是此约束/并集的任何子类型。
例如,您可以使用never
,它是类型System:的底层类型
const throwError = () => {
throw Error('Hello')
}
fn<'a' | 'b'>(throwError())
fn
是否有可能返回a
或b
?不,它将引发错误。也许这不是最好的例子,只是想向您展示不同子类型的含义。
让我们用不同的子类型集调用fn
:
declare var a: 'a' & { tag: 'hello' }
const result = fn(a).tag // undefined
你可能会说:嘿,你没有按规则行事。类型'a' & { tag: 'hello' }
在运行时不可表示。事实上,情况并非如此。tag
在运行时将始终为undefined
。
但是,我们处于类型范围内。我们可以很容易地创建这样的类型。
摘要
请不要将extends
视为等号运算符。它只是意味着T
可以是已定义约束的任意子类型。P.S.类型在TypeScrip中是不变的。这意味着,一旦您创建了带有某些约束的类型T
,则无法返回具有其他约束的相同泛型参数T
。我的意思是,在您的第一个示例中,返回类型T
不能仅为a
或仅为b
。它将始终为a | b
这篇关于为什么TS中的泛型接口不能正确推断类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文