有没有办法在打字稿定义中引用函数自变量?

时间:2018-11-16 09:33:32

标签: typescript types

我有一个{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
}

2 个答案:

答案 0 :(得分:5)

在Typescript中实现梦想:)

您可以使用conditional typesTuples 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的签名。