Typescript泛型中的Bug,还是我很愚蠢? 我现在正处于一个广泛的排字练习(练习14)的中间,而且我似乎被困在我看来像是一个排字错误。但是,由于我没有使用TypeScript的经验,我首先要问一下,这是否真的是一个bug,或者仅仅是我的愚蠢。 在本练习中,您需要将类型添加到一组函数中,这些函数不包含任何数量的参数,如果参数数量不足,则返回子函数。这里的问题是,TypeScript似乎并没有得到正确的泛型。 如果我检查IDE最后一行中使用的func类型,它将被读取为func,其中*是添加的完整类型,而不仅仅是数字。 是我做错了什么,还是这真的是打字稿出了问题 声明函数func(子函数:(arg1:T1,arg2:T2)=>T1); 功能添加(a:编号,b:编号):编号; 功能添加(a:编号):(b:编号)=>编号; 函数add():type of add; 功能添加(a:编号,b:编号){ 如果(a==未定义) 返回添加; 如果(b==未定义){ 返回函数子添加(b?:编号){ 如果(b==未定义) 返回子添加; 返回a+b; } } 返回a+b; } console.log(func(add));

Typescript泛型中的Bug,还是我很愚蠢? 我现在正处于一个广泛的排字练习(练习14)的中间,而且我似乎被困在我看来像是一个排字错误。但是,由于我没有使用TypeScript的经验,我首先要问一下,这是否真的是一个bug,或者仅仅是我的愚蠢。 在本练习中,您需要将类型添加到一组函数中,这些函数不包含任何数量的参数,如果参数数量不足,则返回子函数。这里的问题是,TypeScript似乎并没有得到正确的泛型。 如果我检查IDE最后一行中使用的func类型,它将被读取为func,其中*是添加的完整类型,而不仅仅是数字。 是我做错了什么,还是这真的是打字稿出了问题 声明函数func(子函数:(arg1:T1,arg2:T2)=>T1); 功能添加(a:编号,b:编号):编号; 功能添加(a:编号):(b:编号)=>编号; 函数add():type of add; 功能添加(a:编号,b:编号){ 如果(a==未定义) 返回添加; 如果(b==未定义){ 返回函数子添加(b?:编号){ 如果(b==未定义) 返回子添加; 返回a+b; } } 返回a+b; } console.log(func(add));,typescript,typescript-generics,Typescript,Typescript Generics,实际操作禁止更改测试(最后一行),因此很遗憾,手动提供泛型不是一个选项 另外,这是对实际操作的简化。如果您想查看源代码,这是在test.ts中的一个测试中用作reducer的add函数。这并不完全是一个bug,但它是由于TypeScript的设计限制 您遇到的问题与中的问题相同;当编译器试图从重载函数类型(具有多个调用签名的函数)推断时,它只检查最后一个调用签名。这不是您想要的,编译器可以根据调用方式选择重载签名;不幸的是,编译器无法做到这一点;因此存在设计限制 所以在func(add)中,没有

实际操作禁止更改测试(最后一行),因此很遗憾,手动提供泛型不是一个选项


另外,这是对实际操作的简化。如果您想查看源代码,这是在test.ts中的一个测试中用作reducer的add函数。

这并不完全是一个bug,但它是由于TypeScript的设计限制

您遇到的问题与中的问题相同;当编译器试图从重载函数类型(具有多个调用签名的函数)推断时,它只检查最后一个调用签名。这不是您想要的,编译器可以根据调用方式选择重载签名;不幸的是,编译器无法做到这一点;因此存在设计限制

所以在
func(add)
中,没有发生的是:编译器看到
add
需要匹配类型
(arg1:T1,arg2:T2)=>T1
,所以它选择调用签名
(a:number,b:number)=>number
,因为这是第一个匹配的。因此,
T1
被推断为
number
T2
也被推断为
number

实际情况是:编译器看到
add
需要匹配类型
(arg1:T1,arg2:T2)=>T1
。因为
add
是一个重载函数,所以它会忽略除最后一个调用签名以外的所有内容,最后一个调用签名是
()=>typeof add
。现在这与
匹配(arg:T1,arg2:T2)=>T1
,因为(TL;DR函数忽略调用它们时使用的额外参数通常是安全的,在很多情况下这是可取的)。因此,这两个参数都没有有用的推理站点,但是返回类型
T1
有一个很好的推理站点。因此,编译器推断出
T1
typeof add
T2
unknown
,因为没有更好的推断方法(类型参数隐式地变为unknown,当泛型类型推断失败时,编译器放弃并扩展到约束)

所以你看到
func
unknown
,而不是
number
,对吧?)


我不确定应该对代码做些什么来处理这个问题。我不清楚为什么
func()
需要对
add
进行操作,一般来说,试图在高阶位置使用重载函数往往会遇到您在这里看到的限制。重载函数实际上意味着直接调用,仅此而已

对于这个特定的问题,您可以通过颠倒重载的顺序来处理它,如

declare function add(): typeof add;
declare function add(a: number): (b: number) => number;
declare function add(a: number, b: number): number;
这将导致
T1
T2
根据需要推断为
number

console.log(func(add));
// function func<number, number>(subFunc: (arg1: number, arg2: number) => number): void
console.log(func(add));
//函数func(子函数:(arg1:number,arg2:number)=>number):无效
但是,只要您尝试一些稍微不同的
func
-类似的东西来访问不同的调用签名,您就会再次遇到相同的问题


什么是
add1
?您的代码中没有该名称。如果你的问题是明确的,而不是说“完整类型”(不管是什么意思)。@kaya3是的,这是我将add1重命名为add之前的遗留问题。只是为了澄清而编辑了它。