我有一个函数接受另一个函数的参数。 我想返回一个由传入参数的函数的返回类型配置的通用接口(interface)。
function doSomething <T>(values: Whatever[], getter: (whatever: Whatever) => T): T[] {
return values.map(value => getter(value));
}
然后我想使 getter 函数成为可选的,并为此函数使用默认值。问题发生在那个时候。
function doSomething <T>(values: Whatever[], getter: (whatever: Whatever) => T = val => val): T[] {
return values.map(value => getter(value));
}
所以现在我收到错误消息:
Error:(18, 47) TS2322: Type '(val: Whatever) => Whatever' is not assignable to type '(whatever: Whatever) => T'. Type 'Whatever' is not assignable to type 'T'.
你知道我为什么会收到这个错误吗?
提前谢谢你,
(下面的示例不是我的真实代码,但这更清楚地描述了我的问题)
我正在使用 typescript 2.7.2
最佳答案
问题是默认getter函数的返回类型是Whatever
,但是doSomething
声明要求getter必须返回T
。 T
是泛型类型参数,可以是任何类型,不保证Whatever
与T
兼容。 TypeScript 编译器看不到当提供默认值时,T
不是必需的并且 doSomething
的返回类型是 Whatever[]
。但是你可以用 doSomething
的这些重载声明来表达它:
function doSomething<T>(values: Whatever[], getter: (whatever: Whatever) => T): T[];
function doSomething(values: Whatever[]): Whatever[];
// the implementation must be compatible with both variants
function doSomething<T>(values: Whatever[], getter: (whatever: Whatever) => T | Whatever = val => val ): (T | Whatever)[] {
return values.map(value => getter(value));
}
更新以解决已澄清的问题:
I wanted to avoid to return "Whatever | T" because everytime I will call this function I will have to check the response type (Whatever or T).
当您调用此函数时,仅考虑两个重载签名,TypeScript 在 doSomething()
的调用点进行重载解析时不使用实现签名。事实上,实现返回类型可以简单地声明为 any
,就像在重载 documentation examples 中所做的那样。 - 它仅用于对实现进行类型检查,并且实现通常很明显,因此更严格的类型不会在那里提供太多好处。
I would like to write code to take the return type on the getter function and use as T.
如果在调用doSomething
时省略泛型参数,编译器将从getter
返回类型推断T
。我认为以下示例可以满足您的要求:
interface Whatever { w: string };
function doSomething<T>(values: Whatever[], getter: (whatever: Whatever) => T): T[];
function doSomething(values: Whatever[]): Whatever[];
function doSomething<T>(values: Whatever[], getter: (whatever: Whatever) => T | Whatever = val => val ): (T | Whatever)[] {
return values.map(value => getter(value));
}
function example() {
const getter1 = (whatever: Whatever) => whatever.w; // returns string
const getter2 = (whatever: Whatever) => whatever.w.length; // returns number
const values: Whatever[] = [];
const r0 = doSomething(values); // const r1: Whatever[]
const r1 = doSomething(values, getter1); // const r1: string[]
const r2 = doSomething(values, getter2); // const r2: number[]
}
关于 typescript :函数返回类型取决于输入函数返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51100363/