TypeScript类型操纵:实现getData参数类型随transformData动态变更
解决方案:基于联合类型的条件约束接口
要实现「存在transformData时自动约束getData参数为其返回值」的需求,不能用单一接口,得用联合类型区分两种场景,让TypeScript通过transformData的存在性自动推断类型。
1. 定义核心联合类型IFormData
拆成两个子接口的联合,分别对应「无转换函数」和「有转换函数」的场景:
// 场景1:未传入transformData,getData参数为原始Inputs类型 interface IFormDataWithoutTransform<Inputs> { data: Inputs; transformData?: never; getData?: (values: Inputs) => void; // 可替换为实际业务的返回类型 } // 场景2:传入transformData,getData参数为转换函数的返回值类型 interface IFormDataWithTransform<Inputs, TransformResult> { data: Inputs; transformData: (data: Inputs) => TransformResult; getData?: (values: TransformResult) => void; // 可替换为实际业务的返回类型 } // 联合类型:自动匹配两种场景,默认TransformResult等于Inputs type IFormData<Inputs, TransformResult = Inputs> = | IFormDataWithoutTransform<Inputs> | IFormDataWithTransform<Inputs, TransformResult>;
2. 调整transformer函数的类型约束
补充泛型参数捕获转换结果类型,让TypeScript自动适配联合类型分支:
function transformer<Inputs, TransformResult = Inputs>( options: IFormData<Inputs, TransformResult> ) { const { getData, transformData, data } = options; if (getData) { // TypeScript自动判别分支:存在transformData时用其返回值调用getData if ('transformData' in options && transformData) { getData(transformData(data)); } else { getData(data); } } }
3. 使用场景验证
示例1:未传入transformData
getData参数自动推断为原始Inputs类型:
transformer({ data: { name: 'Alice', age: 25 }, getData: (values) => { // values类型为{ name: string; age: number } console.log(`${values.name} is ${values.age} years old`); } });
示例2:传入transformData
getData参数自动推断为转换函数的返回值类型:
transformer({ data: { name: 'Alice', age: 25 }, transformData: (data) => `${data.name}(${data.age})`, getData: (values) => { // values类型为string console.log(values.toUpperCase()); // 输出ALICE(25) } });
关键细节
- 用
never约束无转换场景的transformData,确保TypeScript能明确区分两个分支 - 泛型默认值
TransformResult = Inputs保证未传转换函数时,默认沿用原始类型 - 联合类型实现自动类型判别,无需手动指定泛型参数
内容的提问来源于stack exchange,提问作者DAYMERE
相关产品推荐
相关产品推荐

