如何限制JavaScript对象中value属性值与对象键名保持一致?
如何限制对象属性的value值与键名一致
当然可以,分编译时约束(TypeScript)和运行时校验(JavaScript)两种场景实现:
一、TypeScript 编译时强制约束
通过泛型类型定义,让编译器在编码阶段就检查每个属性的value是否与键名一致,提前拦截错误:
// 单个属性的类型规则:value必须等于键名类型 type KeyMatchingValue<T extends string> = { value: T; }; // 整个对象的类型规则:每个键Key对应的value必须是Key本身 type StrictObj<K extends string> = { [Key in K]: KeyMatchingValue<Key>; }; // 正确示例:符合约束,编译通过 const validObj: StrictObj<'dog' | 'cat'> = { dog: { value: 'dog' }, cat: { value: 'cat' } }; // 错误示例:编译直接报错,提示类型不匹配 const invalidObj: StrictObj<'dog' | 'cat'> = { dog: { value: 'cat' }, // 错误:"cat" 不能赋值给类型 "dog" cat: { value: 'cat' } };
这种方式无需额外运行时代码,完全由TypeScript编译器把关,适合TS项目。
二、JavaScript 运行时校验
纯JS环境下,可通过工厂函数或Proxy代理保证value与键名一致:
1. 工厂函数自动生成(推荐)
根据传入的键名数组直接生成符合规则的对象,还能冻结对象防止后续修改:
function createKeyMatchingObj(keys) { const result = {}; keys.forEach(key => { result[key] = { value: key }; }); // 冻结对象,禁止后续修改属性或value return Object.freeze(result); } // 使用示例 const obj = createKeyMatchingObj(['dog', 'cat']); console.log(obj.dog.value); // 'dog' obj.dog.value = 'cat'; // 无效(冻结对象无法修改)
2. Proxy代理实时校验
通过Proxy拦截对象的设置操作,一旦发现value与键名不一致就抛出错误,适合需要动态修改属性但要保证规则的场景:
function createValidatedObj(initialData) { // 先校验初始数据是否符合规则 for (const key in initialData) { if (initialData[key].value !== key) { throw new Error(`属性 "${key}" 的value必须等于 "${key}"`); } } return new Proxy(initialData, { set(target, prop, newValue) { const propName = String(prop); // 校验新设置的属性是否符合规则 if (typeof newValue === 'object' && 'value' in newValue) { if (newValue.value !== propName) { throw new Error(`属性 "${propName}" 的value必须等于 "${propName}"`); } } target[prop] = newValue; return true; } }); } // 正确初始化 const obj = createValidatedObj({ dog: { value: 'dog' }, cat: { value: 'cat' } }); // 错误操作会抛出异常 obj.dog = { value: 'cat' }; // 抛出 Error: 属性 "dog" 的value必须等于 "dog"
内容的提问来源于stack exchange,提问作者Paweł
相关产品推荐
相关产品推荐

