我有一个{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
}
答案 0 :(得分:5)
在Typescript中实现梦想:)
您可以使用conditional types和Tuples in rest parameters and spread expressions在Typescript 3.0中实现此目标:
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
答案 1 :(得分:3)
您可以使用自TypeScript 3.1起内置的Parameters<T>
类型来实现此目的:
type B = {
[K in keyof A]: (...a: Parameters<A[K]>) => string
}
“打字稿” docs on conditional types中没有明确记录,但是类似的条件类型,例如ReturnType<T>
,您可以在source中看到它们。
考虑到这一点,我们可以更进一步,并使用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的签名。