如何在TypeScript中判断函数参数是否为可选参数?
判断TypeScript函数参数是否为可选参数
问题描述
定义了如下两个对象:
const object1 = { foo(a?: any) {} } const object2 = { foo(a: any) {} }
请问是否有办法判断foo函数的参数是否为可选参数?目前仅知晓如何判断函数是否无参数:
type NoParams = Parameters<typeof object['foo']> extends [] ? true : false
解决方案
1. 基础判断(区分可选/必选,含允许undefined的必选参数)
利用TypeScript中**可选参数在Parameters类型中会被解析为T | undefined**的特性,可以写出基础判断类型:
type IsParamOptional<T extends (...args: any[]) => any> = Parameters<T>[0] extends undefined ? true : false; // 测试用例 type TestObject1 = IsParamOptional<typeof object1.foo>; // 返回 true type TestObject2 = IsParamOptional<typeof object2.foo>; // 返回 false
注意:如果参数定义为(a: any | undefined) => {},这个类型也会返回true,因为调用时的行为和可选参数一致——可传undefined或不传。
2. 精准判断(严格区分可选参数与允许undefined的必选参数)
如果需要严格识别定义时带?的可选参数,可直接匹配函数类型的语法:
type IsStrictlyOptionalParam<T extends (...args: any[]) => any> = T extends (a?: infer P) => any ? true : false; // 测试用例 type TestStrict1 = IsStrictlyOptionalParam<typeof object1.foo>; // true type TestStrict2 = IsStrictlyOptionalParam<typeof object2.foo>; // false // 区分带undefined的必选参数 const object3 = { foo(a: any | undefined) {} }; type TestStrict3 = IsStrictlyOptionalParam<typeof object3.foo>; // false
3. 多参数场景:判断指定位置的参数是否可选
针对多参数函数,可通过元组递归判断目标位置的参数是否为可选:
type IsNthParamOptional<T extends (...args: any[]) => any, N extends number> = Parameters<T> extends [...infer Rest, infer Last?] ? N extends Parameters<T>['length'] - 1 ? true : IsNthParamOptional<(...args: Rest) => any, N> : false; // 测试用例 const object4 = { foo(a: any, b?: any, c: any) {} }; type TestNth1 = IsNthParamOptional<typeof object4.foo, 1>; // true(第2个参数可选) type TestNth2 = IsNthParamOptional<typeof object4.foo, 0>; // false(第1个参数必选)
内容的提问来源于stack exchange,提问作者undefined
相关产品推荐
相关产品推荐

