如何在保留Record<string, [string, number]>定义时获取TypeScript对象的具体键类型?
解决方案:保留Record约束同时获取具体键类型
问题核心在于直接给ErrorCodeMap标注Record<string, [string, number]>类型时,TypeScript会将对象的键类型拓宽为宽泛的string,丢失了具体的字面量信息。要在保留结构约束的同时获取精确的键类型,可以通过泛型工具函数实现:
// 泛型工具函数:约束对象结构,同时保留字面量类型 function createErrorCodeMap<T extends Record<string, [string, number]>>(map: T): T { return map; } // 使用函数创建对象,无需手动标注Record类型 export const ErrorCodeMap = createErrorCodeMap({ NOT_FOUND: ['1001', 222], ALREADY_EXISTS: ['1002', 111], }); // 现在能获取到精确的键联合类型 export type ErrorCode = keyof typeof ErrorCodeMap; // 类型为 'NOT_FOUND' | 'ALREADY_EXISTS'
原理说明
- 泛型
T extends Record<string, [string, number]>确保传入的对象必须符合Record<string, [string, number]>的结构(即键为字符串,值为[string, number]类型的元组),保证了类型安全。 - 函数返回类型为
T,会完整保留对象的具体字面量类型(包括键的具体值和值的元组内容),避免了类型拓宽。
额外验证
如果后续修改ErrorCodeMap时违反结构约束(比如把值改成['1003', 'xxx']),TypeScript会直接报错;新增错误码时,ErrorCode类型也会自动包含新的键,无需手动维护。
内容的提问来源于stack exchange,提问作者Max101
相关产品推荐
相关产品推荐

