[英]Typescript - How to infer generic in non-invoked function?
请参见下面的示例; 它应该通过对代码的所有合理解释来工作。 有没有人知道为什么没有?
const func_returnsInput = (input: string) : Promise<string> => Promise.resolve(input);
type returnsInput_T = <T>(data: T) => Promise<T>;
const test: returnsInput_T = func_returnsInput;
**ERROR**
Type '(input: string) => Promise<string>' is not assignable to type 'returnsInput_T'.
Types of parameters 'input' and 'data' are incompatible.
Type 'T' is not assignable to type 'string'.(2322)
func_returnsInput
的类型签名是:
const func_returnsInput: (input: string) => Promise<string>
这是一个 function 接受一个string
(并且只接受一个string
)并返回一个Promise<string>
。 您可以稍微更改实现,它仍然符合带注释的类型签名:
const func_returnsInput = (input: string): Promise<string> =>
Promise.resolve(input.toUpperCase());
实现不这样做的事实对编译器并不重要。 它认为调用签名是 function 的外部可见类型,并且隐藏任何具体实现。 如果有人递给我func_returnsInput
,我所知道的是它接受一个string
并返回一个Promise<string>
。 如果我要给它喂一个number
,那么我做错了什么。
现在将其与ReturnsInput_T
类型进行对比:
type ReturnsInput_T = <T>(data: T) => Promise<T>;
这是一个带有泛型类型参数T
的泛型调用签名。 类型参数可以由 function 的调用者随意指定,而不是由 function 的实现者指定。类型ReturnsInput_T
是一个 function,它接受调用者想要的任何值(比如,一个number
),然后返回一个Promise
相同的数据类型(因此, Promise<number>
)。
如果有帮助,您可以将通用调用签名视为T
的所有可能类型的无限交集。 你不能把它写出来,但它的行为就像
type ReturnsInput_T_Infinite =
& ((data: string) => Promise<string>)
& ((data: number) => Promise<number>)
& ((data: boolean) => Promise<boolean>)
& ((data: Date) => Promise<Date>)
& ((data: null) => Promise<null>)
// & ...
现在,为什么不能将func_returnsInput
分配给ReturnsInput
类型的值,这很有可能是有道理的:
const test: ReturnsInput_T = func_returnsInput; // error!
// Type 'T' is not assignable to type 'string'.
test(123); // no error
如果test
确实是ReturnsInput_T
类型,那么我应该被允许调用test(123)
或test(false)
或test(new Date())
或任何我想要的,并取回相同数据类型的Promise
。 但是编译器不知道func_returnsInput
(即使实现恰好这样做)。
所以你得到一个错误!
我认为问题在于您想要使用带有泛型的 function 类型和带有显式字符串的 function 类型。 以下对我有用:
type returnsInput_T = <T>(data: T) => Promise<T>;
function func_returnsInput<T>(input: T) {
return Promise.resolve(input)
}
const test: returnsInput_T = func_returnsInput;
希望对您有所帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.