可以使用不同的约束错误子类型实例化该类型类型、可以使用、实例、错误

2023-09-03 13:33:12 作者:软刺

我为每个函数编写了三个类型相同的函数,让我们来看看它们。

const func: <T extends string, K extends number = any>(arg: T) => K = () => {
  return 1;
};

const anotherFunc = <T extends string, K extends number = any>(arg: T): K => {
  return 1;
};

function someFunc<T extends string, K extends number = any>(arg: T): K {
  return 1;
}

如您所见,我将K定义为它们中的数字,以在每个参数中返回一个数字,但出现了一个奇怪的错误:

静态方法和非静态方法的区别是什么

这是第一个函数:

Type '() => 1' is not assignable to type '<T extends string, K extends number = any>(arg: T) => K'.
  Type 'number' is not assignable to type 'K'.
    'number' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'number'.

下面是最后两个函数:

Type 'number' is not assignable to type 'K'.
  'number' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'number'

我认为这两个错误有相同的道理。为什么TypeScrip无法实现该类型?

谢谢您的帮助。

推荐答案

我不确定这是不是重复的,但请看一下这个answer

以下是第一个示例的简化版本:

const func: <K extends number>() => K = () => {
    return 1;
};
现在,尝试调用此函数:const result = func<42>(); // 42。TS假设返回类型/值为42,但在运行时为1

此外,42 & { WAAAT: () => '?????' }是Numbers的有效子类型。

const result = func<42 & { WAAAT: () => '?????' }>();
result.WAAAT() // ?????
上面的代码在类型脚本中编译,但在运行时抛出运行时错误。 请查看错误消息:

K可以使用不同的约束子类型number

进行实例化

42 & { WAAAT: () => '?????' }是约束number的有效子类型。

因此,不要将extends视为equal运算符。

有关更多示例,请参阅我的article