如何在该TypeScript场景下实现函数返回值的类型安全?
TypeScript类型适配方案:让数组元素保留具体类型而非联合类型
问题核心是当前sap函数返回的rootValues把所有Root的value类型合并成了联合类型,导致IDE无法识别每个索引对应的具体属性。要解决这个问题,需要让TypeScript保留roots数组的元组类型信息,而不是将其扁平化为数组联合类型。
修改后的代码如下:
type RootFunction<T, U> = (input: T) => U; type Root<T, U> = { value: U; }; const root = <T, U>(rootFn: RootFunction<T, U>): ((initialValue: T) => Root<T, U>) => { return initialInput => { let _value: U = rootFn(initialInput); return { get value() { return _value; }, }; }; }; interface TestRootInput { test: string; } interface TestRootOutput { test2: string; } interface TestRootInput2 { test3: string; } interface TestRootOutput2 { test4: string; } const testRoot = root<TestRootInput, TestRootOutput>(input => { return {test2: input.test}; }); const testRoot2 = root<TestRootInput2, TestRootOutput2>(input => { return {test4: input.test3}; }); // 改用元组泛型约束,保留每个元素的具体类型 const sap = <T extends Root<any, any>[]>(sap: { roots: T }) => { const roots = sap.roots; // 映射元组类型,提取每个Root对应的value类型 return { rootValues: roots.map((root) => root.value) as { [K in keyof T]: T[K]['value'] }, }; }; const mySap = sap({roots: [testRoot({test: 'hi'}), testRoot2({test3: 'hi2'})]}); // 现在IDE会正确识别test2属性 console.log(mySap.rootValues[0].test2) // 现在IDE会正确识别test4属性 console.log(mySap.rootValues[1].test4)
关键改动说明
- 调整
sap函数的泛型约束:从T extends BranchSap改为T extends Root<any, any>[],让TypeScript将传入的roots识别为元组类型,而非普通数组,以此保留每个元素的具体类型信息。 - 重构
rootValues的类型推导:使用{ [K in keyof T]: T[K]['value'] }对元组类型做映射,提取每个Root元素对应的value类型,生成对应位置的具体类型,避免了联合类型的扁平化。 - 移除不必要的
as any断言,让类型推导更安全、准确。
内容的提问来源于stack exchange,提问作者msbb
相关产品推荐
相关产品推荐

