题目描述
实现一个泛型AppendArgument<Fn, A>,对于给定的函数类型Fn,以及一个任意类型A,返回一个新的函数G。G拥有Fn的所有参数并在末尾追加类型为A的参数。
type Fn = (a: number, b: string) => number
type Result = AppendArgument<Fn, boolean>
// 期望是 (a: number, b: string, x: boolean) => number
题解
// ============= Test Cases =============
import type { Equal, Expect } from './test-utils'
type Case1 = AppendArgument<(a: number, b: string) => number, boolean>
type Result1 = (a: number, b: string, x: boolean) => number
type Case2 = AppendArgument<() => void, undefined>
type Result2 = (x: undefined) => void
type cases = [
Expect<Equal<Case1, Result1>>,
Expect<Equal<Case2, Result2>>,
// @ts-expect-error
AppendArgument<unknown, undefined>,
]
// ============= Your Code Here =============
type AppendArgument<T extends (...args: any[]) => unknown, U> =
(...args: [...Parameters<T>, U]) => ReturnType<T>
类型约束
使用T extends (...args: any[]) => unknown对T进行约束,确保T是一个可调用函数
内置类型工具
Parameters:这是一个内置的类型工具,它接受一个函数类型T作为参数,并返回一个包含该函数所有参数类型的元组类型。它在 TypeScript 中的定义如下:
/**
* Obtain the parameters of a function type in a tuple
*/
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
ReturnType:这是一个内置的类型工具,它接受一个函数类型T作为参数,并返回该函数的返回类型。它在 TypeScript 中的定义如下:
/**
* Obtain the return type of a function type
*/
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
实现逻辑
Parameters<T>:获取T的参数列表[...Parameters<T>, U]:将T的参数列表与U合并,形成新的参数列表ReturnType<T>:获取T的返回类型(...args: [...Parameters<T>, U]) => ReturnType<T>:定义一个新的函数类型,其参数列表为T的参数列表加上U,返回类型为T的返回类型