我有一个{string: Function}
映射a
:
const a: A = {
foo: (x: string) => 8,
bar: (y: number, z: boolean) => 6,
}
然后我对它进行转换,使每个映射的函数都有不同类型的返回值:
const b: B = {
foo: (x: string) => (8).toString(),
bar: (y: number, z: boolean) => (6).toString(),
}
在TypeScript中,有没有任何方法可以将类型B
描述为源自A
,在我的梦想世界中,我希望能够做到:
type A = {
foo: (string) => number
bar: (number, boolean) => number
}
type B = {
[K in keyof A]: (E in argsof A[K]) => string
}
Typescript中的梦想成真:(
您可以在Typescript 3.0中使用条件类型和rest参数和排列表达式中的元组来实现这一点:
type A = {
foo: (s: string) => number
bar: (n: number, b: boolean) => number
}
type ArgumentTypes<T extends (...a: any[]) => any> = T extends (...a: infer A) => any ? A : [];
type B = {
[K in keyof A]: (...a:ArgumentTypes<A[K]>) => string
}
let b: B;
b.foo("") // works
b.foo(1) // error
您可以使用Typescript 3.1:的内置Parameters<T>
类型来实现这一点
type B = {
[K in keyof A]: (...a: Parameters<A[K]>) => string
}
这在条件类型的Typescript文档中没有明确记录,但类似的条件类型,如ReturnType<T>
,您可以在源代码中看到它们。
考虑到这一点,我们可以更进一步,使用ReturnType<T>
:将B与转换函数的返回类型联系起来
const transformingFunction: (n: number) => string = (n: number) => n.toString();
type B = {
[K in keyof A]: (...a: Parameters<A[K]>) => ReturnType<typeof transformingFunction>
}
所以现在,如果我们想改变转换函数的返回类型,可以在一个地方完成,即在函数本身上,而不会破坏B.的签名