如何检查TypeScript类属性是否非只读以实现安全更新?
解决TypeScript中类只读属性的更新过滤问题
方法一:编译时限制可更新属性(推荐)
通过自定义类型工具,从Person中排除只读属性,让update方法的参数只能接收可写属性,从根源避免传入只读属性导致的错误。
首先定义提取可写属性的类型工具:
type Writable<T> = { -readonly [P in keyof T]: T[P] };
修改Person类的update方法参数类型:
class Person { readonly name: string; age: string; constructor(name: string, age: string) { this.name = name; this.age = age; } update(someProperties: Partial<Writable<Person>>) { let key: keyof typeof someProperties; for (key in someProperties) { // 此时key仅包含可写属性,不会触发只读报错 this[key] = someProperties[key]; } return this; } }
调用update时传入name会直接在编译阶段报错,从源头杜绝问题。
方法二:运行时检查属性可写性
如果需要兼容可能传入只读属性的场景,可以在运行时通过Object.getOwnPropertyDescriptor检查属性是否可写,再执行赋值:
class Person { readonly name: string; age: string; constructor(name: string, age: string) { this.name = name; this.age = age; } update(someProperties: Partial<Person>) { let key: keyof Person; for (key in someProperties) { const descriptor = Object.getOwnPropertyDescriptor(this, key); // 检查属性是否可写 if (descriptor && !descriptor.readonly) { // 类型断言告知TS当前属性可写 (this as Writable<Person>)[key] = someProperties[key]; } } return this; } } // 调用示例:传入name会被过滤,不会报错 const p = new Person("Alice", "25"); p.update({ name: "Bob", age: "26" }); console.log(p.name); // 输出"Alice",name未被修改 console.log(p.age); // 输出"26",age被成功更新
内容的提问来源于stack exchange,提问作者Arst
相关产品推荐
相关产品推荐

