我有几个接受不同参数的函数,但是它们都返回具有相同签名的函数:
const createSum5 = () => (c: number) => c + 5;
const createMultiplyN = (n: number) => (c: number) => n * c;
const createWordsSum = (word: string) => (c: number) => word.length + c;
返回类型始终为(c: number) => number
。有没有一种方法可以在不键入参数的情况下为所有函数键入此返回值?这样我就可以在不失去类型安全性的情况下将它们简化为这样:
createSum5: /* Something here */ = () => c => c + 5;
我已经尝试过这些,但是:
1。此解决方案失去类型安全性:type NumericArg = (...args: any) => (c: number) => number
;
2。我可以为每个函数预先编写函数签名:
type Nfunction = (c: number) => number;
type createSum5Type = () => Nfunction;
...
const createSum5: createSum5Type = () => c => c + 5;
但是那将是乏味的。我希望Typescript像不指定类型一样自动推断参数。
还有其他方法吗?可以做相反的事情(指定具有相同签名的函数,但让Typescript推断返回类型吗?)。
编辑#1: 这是当我谈论相反的例子:
const func1: /* Something here */ = num => '#'.repeat(5);
const func2: /* Something here */ = num => num * num;
func1和func2都具有相同的签名(num: number)
,但返回类型不同。我希望Typescript推断每次我调用func1时,返回类型都是string
,但是对于func2
,返回类型就是数字。
编辑#2:
我的用例无关紧要,但是无论如何我都会添加它。我正在使用Thunks开发一个React-redux应用程序。每个thunk总是返回带有签名(dispatch, getState) => void
的函数,但是它们可以接受不同的参数。经过一番研究,这是我可以找到的不太冗长的版本:
const onFetchUser = (userIds: number[]) : ThunkFunction = dispatch => { ... }
。
如果有一种方法可以让Typescript推断参数,但让我设置返回类型(这是我的问题),那么我可以使它更容易阅读:
const onFetchUser: /* something here */ = (userIds: number[]) => dispatch => {...}
。
答案 0 :(得分:2)
不确定是否唯一的选择,但是一个选择是使用具有通用参数的帮助程序函数,该通用参数将捕获传入的函数的实际类型,但也将强制执行返回类型{{1} }。
(c: number)=> number
我不相信存在另一种选择,打字稿通常不允许对变量进行部分推断(或更具体地讲,受约束的推断),这只能通过函数来完成。
答案 1 :(得分:1)
TypeScript支持关键字infer
,它将允许您保留参数的类型和/或函数的返回类型。
对于条件类型,它看起来像这样:
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
这里有一些有关推断的信息: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html
更新:
您可以使用通用函数来做到这一点:
type numFunc<T> = (arg: T) => (c: number) => number;
const createSum5: numFunc<void> = () => (c: number) => c + 5;
const createMultiplyN: numFunc<number> = (n: number) => (c: number) => n * c;
const createWordsSum: numFunc<string> = (word: string) => (c: number) => word.length + c;
const createSumString: numFunc<number> = () => (c: number) => 'Hello'; //error