能否创建可应用多函数且保留类型信息的类型化函数?
实现类型安全的函数链式调用工具
要实现一个能依次应用多个函数且严格保留类型信息的工具函数makeChain,我们可以通过TypeScript的递归类型推导约束函数链的类型匹配,同时确保定义和调用阶段的类型校验。
类型定义
先通过递归类型校验函数链的兼容性,保证前一个函数的返回类型与后一个函数的参数类型完全匹配:
// 基础函数类型 type Func = (arg: any) => any; // 递归类型:校验函数链的类型连续性 type Pipeable<T extends Func[]> = T extends [ (arg: infer A) => infer B, (arg: B) => infer C, ...infer Rest extends Func[] ] ? [(arg: A) => B, (arg: B) => C, ...Pipeable<[(arg: C) => any, ...Rest]>] : T extends [(arg: infer A) => infer B] ? [(arg: A) => B] : never;
函数实现
基于上述类型实现makeChain,它会按顺序执行传入的函数,并自动推导输入输出类型:
function makeChain<T extends Func[]>(...fns: Pipeable<T>): T extends [(arg: infer Input) => any, ...any[]] ? (arg: Input) => T extends [...any[], (arg: any) => infer Output] ? Output : never : never { return (arg: any) => fns.reduce((prevResult, currentFn) => currentFn(prevResult), arg) as any; }
测试示例
用你提供的函数验证类型校验效果:
const add1 = (n: number) => n + 1; const makeArray = <T>(t: T) => [t]; const getArrLength = (arr: any[]) => arr.length; const makeString = (n: number) => n.toString(); // ❌ 类型错误:makeArray返回数组类型,无法匹配add1的number参数 const chainBad = makeChain(makeArray, add1, getArrLength, makeString); // ✅ 类型匹配:number → number → number[] → number → string const chain = makeChain(add1, makeArray, getArrLength, makeString); chain('1'); // ❌ 类型错误:chain要求输入number类型 var res1: number = chain(1); // ❌ 类型错误:chain返回值为string类型 var res2: string = chain(1); // ✅ 类型正确:返回值为string类型
内容的提问来源于stack exchange,提问作者lonewarrior556
相关产品推荐
相关产品推荐

