我尝试使用 getOwnPropertyDescriptor 方法,但作为回报,普通属性或只读属性总是可写?你知道有什么方法可以检查吗?
readonly打字稿有两种,编译时只读和运行时只读。
由于OP中没有提供代码,我想,根据问题,代码如下:
class Foo {
readonly a = 1
b = 2
}
Run Code Online (Sandbox Code Playgroud)
我们还可以定义一个辅助函数来检查readonly给定对象的属性的-ness
function isWritable<T extends Object>(obj: T, key: keyof T) {
const desc = Object.getOwnPropertyDescriptor(obj, key) || {}
return Boolean(desc.writable)
}
Run Code Online (Sandbox Code Playgroud)
然后我们可以检查readonly-ness:
const foo = new Foo
console.log(isWritable(foo, 'a'), isWritable(foo, 'b'))
// true true
Run Code Online (Sandbox Code Playgroud)
它正在打印,true true因为foo.a并且foo.b在运行时都是可写的,因为readonly打字稿中的关键字对发出的 javascript 代码没有任何作用。
如果我们检查Foo(针对 ES6)发出的代码:
class Foo {
constructor() {
this.a = 1;
this.b = 2;
}
}
Run Code Online (Sandbox Code Playgroud)
a和根本没有区别b。
但是,如果您foo.a在打字稿中为其分配新值,则类型系统会抱怨这a是一个只读属性。这正是readonly关键字的作用:它只提供编译时间约束,永远不会影响运行时行为。
class Foo {
constructor() {
this.a = 1;
this.b = 2;
}
}
Run Code Online (Sandbox Code Playgroud)
如果需要运行时只读属性,则get可以使用语法。
foo.a = 1 // Cannot assign to 'a' because it is a constant or a read-only property.
foo.b = 3 // correct
Run Code Online (Sandbox Code Playgroud)
发出的代码将是:
class Zoo {
constructor() {
this.b = 2;
}
get a() { return 1; }
}
Run Code Online (Sandbox Code Playgroud)
由于 getter 存在于原型上而不是实例上,我们需要isWritable稍微修改函数以覆盖getter.
function isWritable<T extends Object>(obj: T, key: keyof T) {
const desc =
Object.getOwnPropertyDescriptor(obj, key)
|| Object.getOwnPropertyDescriptor(Object.getPrototypeOf(obj), key)
|| {}
return Boolean(desc.writable)
}
Run Code Online (Sandbox Code Playgroud)
然后我们readonly再次检查-ness:
class Zoo {
get a () { return 1 }
b = 2
}
Run Code Online (Sandbox Code Playgroud)
现在zoo.a在编译时和运行时都是只读的。
class Zoo {
constructor() {
this.b = 2;
}
get a() { return 1; }
}
Run Code Online (Sandbox Code Playgroud)
警告
修改后isWritable的仍然不完善,因为它只检查原型链上的一个级别。一个完整的解决方案应该爬上原型链,直到找到一个描述符或到达终点。
| 归档时间: |
|
| 查看次数: |
1048 次 |
| 最近记录: |