TypeScript中通过代理类统一包装对象字面量字符串值
嘿,这个需求用ES6的Proxy就能完美搞定!不用费劲写什么代理类,Proxy可以帮你递归拦截对象的属性访问,自动给所有字符串值加上你要的包裹格式,而且完全不影响原对象的维护性。
直接上完整的TypeScript实现代码:
// 你的原始字符串对象,保持原样就行,不用加任何冗余包裹 const MyNamesStrings = { a: { b: "hello", c: "bye" }, d: { e: "qwerty" } }; // 定义一个递归类型,让TypeScript能正确推断包裹后的字符串类型 type WrappedObject<T> = { [K in keyof T]: T[K] extends string ? `[${T[K]}]` : T[K] extends object ? WrappedObject<T[K]> : T[K]; }; // 核心工具函数:创建递归代理,处理嵌套对象 function createWrappedProxy<T extends object>(obj: T): WrappedObject<T> { return new Proxy(obj, { get(target, prop) { const value = (target as any)[prop]; // 如果是嵌套对象,继续用代理包裹;如果是字符串,返回带[]的结果 if (typeof value === 'object' && value !== null) { return createWrappedProxy(value); } else if (typeof value === 'string') { return `[${value}]`; } // 非字符串/对象类型直接返回(比如数字、布尔等) return value; } }) as WrappedObject<T>; } // 生成你要的MyNames代理对象 const MyNames = createWrappedProxy(MyNamesStrings); // 测试一下,完全符合你的需求 const ab = MyNames.a.b; // 类型提示是 "[hello]",实际值也是 "[hello]" const de = MyNames.d.e; // 类型提示是 "[qwerty]",实际值也是 "[qwerty]" console.log(ab); // 输出: [hello]
为什么这么做?
- 无冗余维护:原始对象
MyNamesStrings完全保持干净,要修改字符串内容直接改这里就行,不用管包裹格式。 - 递归处理:不管你的对象嵌套多少层,Proxy都会自动深入处理,确保所有字符串都被包裹。
- 类型安全:通过
WrappedObject递归类型,TypeScript能准确推断每个属性的类型,写代码时有完整的类型提示,避免出错。
如果你的对象里还有其他类型(比如数字、布尔),这个实现也能兼容,只会包裹字符串类型的值,其他类型原样返回。
内容的提问来源于stack exchange,提问作者PickleHerring
相关产品推荐
相关产品推荐

