[英]Typescript - How to infer generic in non-invoked function?
See the example below;请参见下面的示例; it should be working by all reasonable interpretation of the code.
它应该通过对代码的所有合理解释来工作。 Does anybody have any insight on why it doesn't?
有没有人知道为什么没有?
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)
The type signature of func_returnsInput
is: func_returnsInput
的类型签名是:
const func_returnsInput: (input: string) => Promise<string>
That is specifically a function that accepts a string
(and only a string
) and returns a Promise<string>
.这是一个 function 接受一个
string
(并且只接受一个string
)并返回一个Promise<string>
。 You could change the implementation slightly and it would still conform to the annotated type signature:您可以稍微更改实现,它仍然符合带注释的类型签名:
const func_returnsInput = (input: string): Promise<string> =>
Promise.resolve(input.toUpperCase());
The fact that the implementation doesn't do that is not important to the compiler.实现不这样做的事实对编译器并不重要。 It considers the call signature to be the externally-viewable type of the function, and any specific implementation to be hidden.
它认为调用签名是 function 的外部可见类型,并且隐藏任何具体实现。 If someone hands me
func_returnsInput
, all I know is that it takes a string
and returns a Promise<string>
.如果有人递给我
func_returnsInput
,我所知道的是它接受一个string
并返回一个Promise<string>
。 If I were to feed it, say, a number
, then I have done something wrong.如果我要给它喂一个
number
,那么我做错了什么。
Contrast that now with the type ReturnsInput_T
:现在将其与
ReturnsInput_T
类型进行对比:
type ReturnsInput_T = <T>(data: T) => Promise<T>;
That is a generic call signature with a generic type parameter T
.这是一个带有泛型类型参数
T
的泛型调用签名。 The type parameter may be specified at will by the caller of the function, not by the implementer of the function. The type ReturnsInput_T
is a function that accepts any value the caller wants (say, a number
), and then returns a Promise
of the same data type (so, Promise<number>
).类型参数可以由 function 的调用者随意指定,而不是由 function 的实现者指定。类型
ReturnsInput_T
是一个 function,它接受调用者想要的任何值(比如,一个number
),然后返回一个Promise
相同的数据类型(因此, Promise<number>
)。
If it helps, you can think of a generic call signature as an infinite intersection of all possible types for T
.如果有帮助,您可以将通用调用签名视为
T
的所有可能类型的无限交集。 You can't write that out, but it behaves like你不能把它写出来,但它的行为就像
type ReturnsInput_T_Infinite =
& ((data: string) => Promise<string>)
& ((data: number) => Promise<number>)
& ((data: boolean) => Promise<boolean>)
& ((data: Date) => Promise<Date>)
& ((data: null) => Promise<null>)
// & ...
Now it hopefully makes sense why you cannot assign func_returnsInput
to a value of type ReturnsInput
:现在,为什么不能将
func_returnsInput
分配给ReturnsInput
类型的值,这很有可能是有道理的:
const test: ReturnsInput_T = func_returnsInput; // error!
// Type 'T' is not assignable to type 'string'.
test(123); // no error
If test
is truly of type ReturnsInput_T
, then I should be allowed to call test(123)
, or test(false)
or test(new Date())
or anything I want, and get back a Promise
of the same data type.如果
test
确实是ReturnsInput_T
类型,那么我应该被允许调用test(123)
或test(false)
或test(new Date())
或任何我想要的,并取回相同数据类型的Promise
。 But func_returnsInput
cannot be known to do that by the compiler (even if the implementation happens to do this).但是编译器不知道
func_returnsInput
(即使实现恰好这样做)。
And so you get an error!所以你得到一个错误!
I think the problem is that you want to use the type of a function that takes a generic with a function that takes explicitly a string.我认为问题在于您想要使用带有泛型的 function 类型和带有显式字符串的 function 类型。 The following works for me:
以下对我有用:
type returnsInput_T = <T>(data: T) => Promise<T>;
function func_returnsInput<T>(input: T) {
return Promise.resolve(input)
}
const test: returnsInput_T = func_returnsInput;
Hope it helped希望对您有所帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.