Typescript 能够推断一些泛型函数的类型,但它有一些限制。
由于generic section of the handbook 中没有任何信息,我决定进行一些测试,看看它在哪里崩溃。
- 一个带有 1 个参数的简单函数。
function genericFunction<T>(value: T): T {
return value;
}
// type of val is Window
let val = genericFunction(window);
这样可以,不需要手动指定T的类型。
- 具有 2 个通用参数的函数。
function genericFunction2<T>(value: T, anotherValue: T) : T {
return value;
}
// type of val is String
let val = genericFunction2("b", "5");
// compilation error type of T can't be inferred from usage
let anotherVal = genericFunction2("b", 5);
这样可以,不需要手动指定T的类型。
- 接收回调和值的函数。
function callBackAndValue<T>(action: (value: T) => T, value: T): T {
return action(value);
}
// type of val is string
let val = callBackAndValue((value: string) => value + "5", "abc ");
这样可以,不需要手动指定T的类型。
- 接收回调和值但返回承诺的函数。
function callBackAndValueWithPromise<T>(action: (value: T) => T, value: T): Promise<T> {
return new Promise<T>((resolve, reject) => {
resolve(action(value));
});
}
// type of val is Promise<string>
let val = callBackAndValueWithPromise((value: string) => value + "5", "abc ");
这样可以,不需要手动指定T的类型。
- 只接收从 T 到 T 的函数的函数
function onlyCallback<T>(action: () => T) : T {
return action();
}
// type of val is string
let val = onlyCallback(()=> "abc");
这样可以,不需要手动指定T的类型。
- 一个从无到有的函数接收一个返回承诺的 T 的函数。
function onlyCallbackWithPromise<T>(action: () => T): Promise<T> {
return new Promise<T>((resolve, reject) => {
resolve(action());
});
}
// the type of val is Promise<string>
let val = onlyCallbackWithPromise(()=> "abc");
这行得通,无需手动指定 T 的类型。
- 一个函数接收一个函数,该函数接受一个函数。问题中的案例。
function typeFromCallbackOfCallback<T>(action: (callback: (value: T) => void) => void): Promise<T> {
return new Promise<T>((resolve, reject) => {
action((value) => {
resolve(value);
});
});
}
// here the compiler fails to infer the type cb should take as a parameter and it seems to default to object({})
// type of Val is Promise<{}>
let val = typeFromCallbackOfCallback(cb => cb("abc"));
这不再有效,需要手动指定类型。
由于目前编译器受到限制,我猜你不得不为这种情况指定类型。这也是手册中给出的解决方案,也适用于类型推断失败的情况。
添加另一个 T 类型的参数可以修复它,但它与您的情况不太匹配。
function lastOne<T>(action: (callback: (value: T) => void) => void, b: T): Promise<T> {
return new Promise<T>((resolve, reject) => {
action((value) => {
resolve(value);
});
});
}
// type of var is Promise<string>
let var = lastOne(cb => cb("abc"), "a");
这行得通,无需手动指定 T 的类型。