如何通过TypeScript函数实现对象字面量类型的精确值映射?
精确值类型映射的实现方案
你需要对用as const断言的对象进行精确值映射,让每个键对应其值转换后的精确字面量类型,而非宽泛的string或所有值转换后的联合类型。以下是具体实现方案:
通用实现(仅处理值)
利用TypeScript泛型函数类型推断+映射类型,结合const泛型断言保留对象的精确字面量类型,实现每个键的独立精确映射:
const mapObjExact = <const T extends Record<string, unknown>, F extends <V>(v: V) => unknown>( obj: T, mapFn: F ): { [K in keyof T]: ReturnType<(typeof mapFn)<T[K]>> } => ({} as any);
使用示例
const obj = { num1: 1, num2: 2, } as const; // 返回类型:{ readonly num1: "1"; readonly num2: "2"; } const stringResult = mapObjExact(obj, (v) => `${v}` as const); // 支持任意精确转换,比如值自增1 const numberResult = mapObjExact(obj, (v) => v + 1 as const); // 返回类型:{ readonly num1: 2; readonly num2: 3; }
支持传入键的版本(可选)
如果需要在映射函数中使用键的信息,可扩展为带键的精确映射:
const mapObjExactWithKey = <const T extends Record<string, unknown>>( obj: T, mapFn: <K extends keyof T>(key: K, value: T[K]) => `${K}:${T[K]}` ): { [K in keyof T]: `${K}:${T[K]}` } => ({} as any); // 返回类型:{ readonly num1: "num1:1"; readonly num2: "num2:2"; } const keyResult = mapObjExactWithKey(obj, (k, v) => `${k}:${v}` as const);
原实现失败原因
你之前的mapObjExact中,泛型F定义为<K extends keyof T>(k:K, v: T[K]) => unknown,返回类型直接使用ReturnType<F>会取所有调用场景的返回类型联合(即"1" | "2"),无法为每个K单独关联对应的返回类型。
新实现通过让mapFn成为针对单个值的泛型函数,在映射类型中为每个K单独调用mapFn<T[K]>,TypeScript会自动推断出每个键对应的精确返回类型,结合const泛型断言保留原对象的字面量类型,最终得到你需要的精确映射结果。
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

