如何实现TypeScript管道步骤数组的类型安全签名自动推导?
实现方案
受TypeScript类型标注的推导规则限制,无法直接通过const steps: Pipeline<4> = [...]的形式从赋值内容反向推导泛型参数,我们可以用泛型工具函数实现等价体验,无需手动声明任何步骤返回值类型,自动完成相邻步骤的类型校验:
type Step<In, Out> = { description: string; execute: (param: In) => Out; }; // 递归构造合法的步骤链:前一步的输出 = 后一步的输入 type BuildPipeline<Steps extends unknown[], PreviousOutput = void> = Steps extends [infer FirstStep, ...infer RestSteps] ? FirstStep extends Step<PreviousOutput, infer CurrentOutput> ? [FirstStep, ...BuildPipeline<RestSteps, CurrentOutput>] : never : []; // 泛型工具函数,自动推导步骤类型并做校验 function createPipeline<const Steps extends unknown[]>(steps: BuildPipeline<Steps>) { return steps; }
使用示例
不需要手动传入任何类型参数,TypeScript会自动推导所有步骤的入参/出参类型,类型不匹配时会直接报错:
const steps = createPipeline([ { description: 'Step 1', execute: () => 1 }, // 此处x自动推导为number类型 { description: 'Step 2', execute: (x) => x.toString() }, // 此处x自动推导为string类型 { description: 'Step 3', execute: (x) => Boolean(x) }, // 此处x自动推导为boolean类型 { description: 'Step 4', execute: (x) => ({ x }) }, ]);
可选:显式约束步骤长度
如果你需要固定步骤数量,多传/少传都报错,可以调整工具函数增加长度参数:
function createPipeline<N extends number, const Steps extends unknown[]>( expectedLength: N, steps: BuildPipeline<Steps> & { length: N } ) { return steps; } // 必须传入4个步骤,否则直接报错 const steps = createPipeline(4, [ { description: 'Step 1', execute: () => 1 }, { description: 'Step 2', execute: (x) => x.toString() }, { description: 'Step 3', execute: (x) => Boolean(x) }, { description: 'Step 4', execute: (x) => ({ x }) }, ]);
注:泛型上的
const修饰符是TypeScript 5.0+的特性,用于保留更精确的字面量类型,低版本TS移除该修饰符即可正常使用,不影响核心的类型校验能力。
内容的提问来源于stack exchange,提问作者Christian Ivicevic
相关产品推荐
相关产品推荐

