题目描述
实现内置的 Parameters 类型,而不是直接使用它,可参考TypeScript官方文档。
例如:
const foo = (arg1: string, arg2: number): void => {}
type FunctionParamsType = MyParameters<typeof foo> // [arg1: string, arg2: number]
题解
// ============= Test Cases =============
import type { Equal, Expect } from './test-utils'
const foo = (arg1: string, arg2: number): void => { }
const bar = (arg1: boolean, arg2: { a: 'A' }): void => { }
const baz = (): void => { }
type cases = [
Expect<Equal<MyParameters<typeof foo>, [string, number]>>,
Expect<Equal<MyParameters<typeof bar>, [boolean, { a: 'A' }]>>,
Expect<Equal<MyParameters<typeof baz>, []>>,
]
// ============= Your Code Here =============
type MyParameters<T extends CallableFunction> = T extends (...args: infer U) => unknown ? U : never
使用T extends CallableFunction对传入的类型参数T进行约束,确保T是一个可调用的函数类型
Function类型只约束了函数的name属性,太宽泛了,不适合检查可调用函数。Function类型的实现如下:
interface Function {
readonly name: string;
}
CallableFunction是一个扩展了Function的接口,提供了更精确的可调用函数类型描述。CallableFunction类型的实现如下:
interface CallableFunction extends Function {
apply<T, R>(this: (this: T) => R, thisArg: T): R;
apply<T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, args: A): R;
call<T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A): R;
bind<T>(this: T, thisArg: ThisParameterType<T>): OmitThisParameter<T>;
bind<T, A extends any[], B extends any[], R>(this: (this: T, ...args: [...A, ...B]) => R, thisArg: T, ...args: A): (...args: B) => R;
}
使用T extends (...args: infer U) => unknown将函数T的参数类型存储在U中,如果T是可调用函数,返回U,否则返回never