如何基于类型生成函数签名?void/never类型参数省略实现
解决方案:基于属性类型自动适配set方法的参数个数
实现思路
通过TypeScript的条件类型结合Rest参数,根据目标属性的类型动态生成不同的函数签名:
- 当属性类型为
void或never时,set方法仅需传入key参数 - 其他类型下,
set方法需传入key和对应类型的value参数
修改后的代码实现
type DataBool = { update: boolean }; type DataVoid = { update: void }; type DataNever = { update: never }; type Distribution<T> = { on: <K extends keyof T>(key: K, listener: (value: T[K]) => void) => void; set: <K extends keyof T>( ...args: T[K] extends void | never ? [key: K] : [key: K, value: T[K]] ) => void; }; // 测试boolean类型 const distBool: Distribution<DataBool> = { on: (key, listener) => {}, set: (key, value) => {} }; distBool.set('update', true); // 正常工作,必须传入第二个参数 // 测试void类型 const distVoid: Distribution<DataVoid> = { on: (key, listener) => {}, set: (key) => {} }; distVoid.set('update'); // 正常工作,无需传入第二个参数 // 测试never类型 const distNever: Distribution<DataNever> = { on: (key, listener) => {}, set: (key) => {} }; distNever.set('update'); // 正常工作,无需传入第二个参数
原理说明
- 条件类型判断:
T[K] extends void | never会检查当前属性的类型是否为void或never - Rest参数适配:根据条件结果返回不同长度的参数数组类型:
- 条件成立时,参数数组仅包含
key: K,对应函数签名为(key: K) => void - 条件不成立时,参数数组包含
key: K和value: T[K],对应函数签名为(key: K, value: T[K]) => void
- 条件成立时,参数数组仅包含
- 这种实现既没有将第二个参数设为可选,也没有使用
undefined,完全符合需求。
内容的提问来源于stack exchange,提问作者Marcel Armada-Castellon
相关产品推荐
相关产品推荐

