为什么TS中的泛型接口不能正确推断类型? [英] Why can't the generic interface in TS infer the type correctly?

查看:0
本文介绍了为什么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’。 在上面示例中,result2,但在运行时它等于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总是等于abT可以是此约束/并集的任何子类型。 例如,您可以使用never,它是类型System:

的底层类型
const throwError = () => {
  throw Error('Hello')
}

fn<'a' | 'b'>(throwError())

fn是否有可能返回ab?不,它将引发错误。也许这不是最好的例子,只是想向您展示不同子类型的含义。

让我们用不同的子类型集调用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆