Skip to content

Repository files navigation

typescript-plugin-mark-fields

npm version License

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-fields

用法

TypeScript Compiler API

import 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

// 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 (ts-loader)

// 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, {})],
          }),
        },
      },
    ],
  },
};

ttypescript / ts-patch

tsconfig.json 中添加:

{
  "compilerOptions": {
    "plugins": [
      { "transform": "typescript-plugin-mark-fields" }
    ]
  }
}

然后用 ttsc 代替 tsc 编译。

License

MIT

About

Auto-mark class fields on prototype via static block for runtime introspection

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages