取以下函数:
function test<T>(this: { value: T }) {
return this.value;
}
Run Code Online (Sandbox Code Playgroud)
如果您使用call
, apply
orbind
并提供this
上下文,TypeScript 将不会推断提供的类型,并且unknown
在这种情况下它将返回。
const a = test.apply({ value: 1 }); // a: unknown
const b = test.call({ value: 'b' }); // b: unknown
const fn = test.bind({ value: true }); // fn: () => unknown
Run Code Online (Sandbox Code Playgroud)
好的,这可能是因为apply
,例如,被声明为apply<T, R>(this: (this: T) => R, thisArg: T): R
,所以它需要您告知R
返回类型。但如果你只显式声明函数的类型test
,你将得到正确的类型:
const typed = (test<number>).apply({ value: 1 }); // typed: number
Run Code Online (Sandbox Code Playgroud)
为什么会发生这种情况?为什么它没有推断,R
但当我提供类型时它却推断出来了?
bind
// call
TypeScriptsupply
3.2 中引入的支持(在microsoft/TypeScript#27028中实现)无法真正正确处理重载或泛型函数。根据文档,“在泛型函数上使用这些方法时,类型参数将被替换为[类型unknown
]”(它表示空对象类型{}
,但自 TypeScript 3.5 以来一直如此unknown
,如microsoft/TypeScript#30637中实现的那样)。这解释了您所看到的行为。microsoft/TypeScript#54707有一个开放的功能请求,要求改进此处的支持,但目前它还不是该语言的一部分。
至于为什么它与 一起工作(test<number>)
,这是一个实例化表达式,其中指定的类型参数被替换为泛型函数类型参数,而不调用该函数。所以test<number>
不再是一个通用函数:
function test<T>(this: { value: T }) {
return this.value;
}
type Test = typeof test // <T>(this: {value: T}) => T
const tn = test<number>;
type TestNumber = typeof tn // (this: { value: number; }) => number
Run Code Online (Sandbox Code Playgroud)
它只是特定的函数类型,(this: { value: number }) => number
//bind
应该按需要工作。call
apply
归档时间: |
|
查看次数: |
106 次 |
最近记录: |