打字稿:获取函数类型的最后一个参数的类型

ksm*_*816 10 typescript

假设我有一个函数类型,例如

type somefntype = (a: number, b: string, c: boolean) => void
Run Code Online (Sandbox Code Playgroud)

我需要该函数类型最后一个参数的类型:

type lastparamtype = LastParameter<somefntype> // lastparamtype == boolean
Run Code Online (Sandbox Code Playgroud)

我如何定义LastParameter?

jca*_*alz 17

更新:TypeScript 4.0 引入了可变元组类型,这意味着Last现在可以简单地实现为

type Last<T extends any[]> = T extends [...infer I, infer L] ? L : never; 
Run Code Online (Sandbox Code Playgroud)

其余的工作正常:

type LastParameter<F extends (...args: any)=>any> = Last<Parameters<F>>;
type somefntype = (a: number, b: string, c: boolean) => void
type lastparamtype = LastParameter<somefntype> // boolean
Run Code Online (Sandbox Code Playgroud)

Playground 链接到代码


TypeScript 3.0在 rest 和 spread 表达式中引入了元组类型,特别是允许在函数参数列表和元组类型之间进行编程转换。Parameters<F> 在标准库中定义了一个类型别名,它以元组形式返回函数的参数列表。

这很烦人,但可以获取具有固定但任意长度的元组类型的最后一个元素:

// Tail<T> returns a tuple with the first element removed
// so Tail<[1, 2, 3]> is [2, 3]
// (works by using rest tuples)
type Tail<T extends any[]> = 
  ((...t: T)=>void) extends ((h: any, ...r: infer R)=>void) ? R : never;

// Last<T> returns the last element of the tuple
// (works by finding the one property key in T which is not in Tail<T>)
type Last<T extends any[]> = T[Exclude<keyof T, keyof Tail<T>>];
Run Code Online (Sandbox Code Playgroud)

把这些放在一起你得到

type LastParameter<F extends (...args: any)=>any> = Last<Parameters<F>>;
Run Code Online (Sandbox Code Playgroud)

我们可以测试一下:

type somefntype = (a: number, b: string, c: boolean) => void
type lastparamtype = LastParameter<somefntype> // boolean
Run Code Online (Sandbox Code Playgroud)

在我看来很好。 代码链接