TypeScript中如何约束对象键与value值一致并生成_Option类型
解决TypeScript中对象键与内部value值一致的类型约束问题
需求说明
需要创建TypeScript类型,强制对象的键与其内部value字段的值完全一致,同时通过函数从符合该规则的数据中提取_Option类型的数组。示例数据及函数调用如下:
const data = { asd: { value: "asd", label: "Asd", active: false, }, qwe: { value: "qwe", label: "Qwe", active: true, }, }; const options = getOptionsFromDetails(data);
遇到的问题
原代码尝试用泛型索引签名约束输入,触发警告:An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead.;改用映射类型后又出现值为unknown的问题,原代码如下:
type _Option<TValue extends string> = { value: TValue; label: string; }; export const getOptionsFromDetails = <TKey extends string>( details: { [key: TKey]: { value: TKey; label: string; active: boolean; }; }, ): _Option<TKey>[] =>
解决方案
使用泛型映射类型实现精准约束,让泛型参数捕获整个输入对象的结构,再通过映射类型强制每个键与对应value值一致:
完整代码实现
type _Option<TValue extends string> = { value: TValue; label: string; }; export const getOptionsFromDetails = <T extends Record<string, { value: string; label: string; active: boolean }>>( details: { [K in keyof T]: { value: K; label: T[K]['label']; active: T[K]['active'] } } ): _Option<keyof T & string>[] => { return Object.values(details).map(({ value, label }) => ({ value, label })); };
代码说明
- 泛型参数
T:先捕获输入对象的基础结构,确保每个属性都包含value、label、active字段 - 映射类型约束:通过
{ [K in keyof T]: ... }强制每个键K对应的value字段类型必须等于K,同时保留label和active的原有类型 - 返回值类型:
_Option<keyof T & string>[]确保返回的是由对象键作为value的_Option数组,& string过滤掉可能的symbol类型键
验证效果
- 符合规则的输入会通过类型检查,返回的
options类型为_Option<"asd" | "qwe">[] - 若键与
value不匹配,会直接触发类型错误:const invalidData = { asd: { value: "wrong", // 类型错误:"wrong"不能赋值给类型"asd" label: "Asd", active: false, }, }; getOptionsFromDetails(invalidData); // 类型检查失败
内容的提问来源于stack exchange,提问作者Dawid Studnicki
相关产品推荐
相关产品推荐

