如何阻止TypeScript移除未赋值的静态类字段?
问题背景
在原生JavaScript中,未赋值的静态类字段会被保留在类的自身属性上,可通过Object.keys枚举:
class test { static 'a-a'; static 'b-b'; static 'c-c'; } console.log(Object.keys(test)) // 输出: ['a-a', 'b-b', 'c-c']
但在TypeScript中编写类似代码时,编译后的JavaScript会丢失这些静态字段:
class test { static 'a-a': unknown; static 'b-b': unknown; static 'c-c': unknown; } console.log(Object.keys(test))
编译后的输出:
"use strict"; class test { } console.log(Object.keys(test)); // 输出: []
为什么字段会被移除?
TypeScript中仅声明类型的静态成员(如static 'a-a': unknown;)属于纯类型标注,这类信息在编译阶段会被完全擦除——TypeScript的核心设计之一就是类型系统仅作用于开发阶段,不会影响运行时代码。
而原生JavaScript里的static 'a-a';是ES6+的类字段语法,即便未赋值,也会在类的自身上创建值为undefined的属性,因此能被Object.keys检测到。
如何修改以保留这些字段?
要让TypeScript将静态字段保留到运行时,必须为其添加运行时的初始化逻辑,以下是两种可行方案:
方案1:显式赋值为undefined
直接给静态字段赋值undefined,这样TypeScript会将其编译为原生的类字段声明:
class test { static 'a-a': unknown = undefined; static 'b-b': unknown = undefined; static 'c-c': unknown = undefined; } console.log(Object.keys(test))
编译后的JavaScript会保留这些字段,运行时输出与原生JS一致。
方案2:使用静态初始化块
如果需要集中管理初始化逻辑,可使用ES2022引入的静态块,在其中为类添加属性:
class test { // 保留类型标注 static 'a-a': unknown; static 'b-b': unknown; static 'c-c': unknown; static { this['a-a'] = undefined; this['b-b'] = undefined; this['c-c'] = undefined; } } console.log(Object.keys(test))
编译后的JS会包含静态块代码,执行时会为类添加指定属性,同样能被Object.keys枚举。
内容的提问来源于stack exchange,提问作者Jan Kretschmer
相关产品推荐
相关产品推荐

