如何根据参数值缩小类型?使factory返回精确类型而非any
解决方案
要让factory函数返回精确类型而非any,同时正确缩小库的类型,可以通过以下方式调整代码:
完整修改后的代码
const libA = { p: () => 0, q: () => 1, }; const libB = { x: () => 'x', y: () => 'y', }; // 定义库标识与对应库类型的映射,辅助TypeScript做类型推断 type LibMap = { a: typeof libA; b: typeof libB; }; // 调整泛型约束,关联库标识与对应合法键 function factory<T extends keyof LibMap>(library: T, key: keyof LibMap[T]) { // 通过switch分支做类型窄化,让TypeScript精准识别当前库的类型 const libFn = (() => { switch (library) { case 'a': return libA[key as keyof typeof libA]; case 'b': return libB[key as keyof typeof libB]; default: throw new Error(`Unknown library: ${library}`); } })(); return function () { return libFn(); }; } // 此时fnP的类型为() => number,调用返回值类型精确为number const fnP = factory('a', 'p'); const result = fnP(); // result类型为number
关键说明
LibMap类型映射:将库标识与对应的库对象类型绑定,让TypeScript明确每个标识对应的库结构,为后续类型推断提供清晰依据。- switch-case类型窄化:分支判断会让TypeScript自动将
library的类型在每个分支中缩小为具体的'a'或'b',从而精准推断key对应的函数类型。 - 泛型关联约束:
T extends keyof LibMap确保传入的library是合法标识,key: keyof LibMap[T]保证key是当前库的有效键,避免非法参数传入。
如果偏好更简洁的写法,也可以用类型断言辅助推断(类型安全性略低于switch-case):
function factory<T extends keyof LibMap>(library: T, key: keyof LibMap[T]) { const libMap: LibMap = { a: libA, b: libB }; // 用类型断言明确libFn的返回类型 const libFn = libMap[library][key] as () => ReturnType<LibMap[T][typeof key]>; return function () { return libFn(); }; }
内容的提问来源于stack exchange,提问作者spikef
相关产品推荐
相关产品推荐

