TypeScript transformer 插件。编译期自动在每个 class 头部插入 static {} 块,将实例字段显式标记到 prototype 上,使运行时代码能在实例化之前感知类有哪些字段。
输入:
const TAG = 'tag';
class Animal {
static count = 0;
name;
type = 'dog';
[TAG];
legs = 4;
}输出:
const TAG = 'tag';
class Animal {
static {
this.prototype.name = undefined;
this.prototype.type = undefined;
this.prototype[TAG] = undefined;
this.prototype.legs = undefined;
}
static count = 0;
name;
type = 'dog';
[TAG];
legs = 4;
}
static {}中的this指向类自身,无论具名类还是匿名类表达式均有效。
| 字段类型 | 示例 | 处理 |
|---|---|---|
| 普通标识符字段 | name |
✅ this.prototype.name = undefined |
| 带初始值的字段 | type = "dog" |
✅ this.prototype.type = undefined |
| 计算属性名 | [TAG] |
✅ this.prototype[TAG] = undefined |
| 字符串字面量 key | "my-field" |
✅ this.prototype["my-field"] = undefined |
| 数字字面量 key | 0 |
✅ this.prototype[0] = undefined |
| 类表达式 | const X = class { ... } |
✅ 同 class 声明一样生效 |
| static 字段 | static count = 0 |
❌ 跳过 |
| 方法 / getter / setter | greet() {} |
❌ 跳过 |
| 无实例字段的类 | 纯方法 | ❌ 不插入 static block |
- 装饰器方案补充:未写装饰器的字段也会被标记到 prototype
- 运行时反射 / ORM / 序列化:框架在实例化前就能收集字段元数据
- AOP 切面注入:在字段读取/写入时插入拦截逻辑
- 与
useDefineForClassFields一致的可见语义:让运行时代码明确知道字段的存在
- TypeScript >= 4.4(需要
static {}语法支持)
npm install typescript-plugin-mark-fieldsimport ts from 'typescript';
import plugin from 'typescript-plugin-mark-fields';
const program = ts.createProgram(['src/index.ts'], {
target: ts.ScriptTarget.ESNext,
});
const transformers: ts.CustomTransformers = {
before: [plugin(program, {})],
};
program.emit(undefined, undefined, undefined, undefined, transformers);// rollup.config.js
import typescript from '@rollup/plugin-typescript';
import plugin from 'typescript-plugin-mark-fields';
export default {
input: 'src/index.ts',
plugins: [
typescript({
transformers: (program) => ({
before: [plugin(program, {})],
}),
}),
],
};// webpack.config.js
const plugin = require('typescript-plugin-mark-fields');
module.exports = {
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
options: {
getCustomTransformers: (program) => ({
before: [plugin(program, {})],
}),
},
},
],
},
};在 tsconfig.json 中添加:
{
"compilerOptions": {
"plugins": [
{ "transform": "typescript-plugin-mark-fields" }
]
}
}然后用 ttsc 代替 tsc 编译。
MIT