如何基于类中带指定装饰器的属性生成TypeScript联合类型
实现提取带特定装饰器属性的泛型类型
TypeScript的类型系统本身无法直接识别运行时装饰器,得结合元数据来实现这个需求,具体步骤如下:
1. 实现带元数据记录的装饰器
借助reflect-metadata库,让@Attribute()装饰器把属性名记录到类的元数据里:
import 'reflect-metadata'; // 定义唯一的元数据标识 const ATTRIBUTE_KEY = Symbol('attribute'); function Attribute() { return function(target: any, propertyKey: string) { // 读取已有属性列表,没有则初始化为空数组 const existingAttrs = Reflect.getMetadata(ATTRIBUTE_KEY, target) || []; // 将当前属性名存入元数据 Reflect.defineMetadata(ATTRIBUTE_KEY, [...existingAttrs, propertyKey], target); }; }
2. 定义泛型类型ExtractAttributes
通过读取类原型上的元数据,提取对应的属性名联合类型:
type ExtractAttributes<T extends new (...args: any[]) => any> = (typeof Reflect.getMetadata(ATTRIBUTE_KEY, T.prototype))[number];
3. 测试示例
用你提供的Image类测试,就能得到预期的类型:
class Image { @Attribute() public id: number; @Attribute() public src: string; public alt: string; } type ImageAttributes = ExtractAttributes<typeof Image>; // ImageAttributes 的类型为 "id" | "src",完全符合需求
注意事项
- 需要先安装
reflect-metadata:npm install reflect-metadata - 在
tsconfig.json中开启以下选项:{ "compilerOptions": { "experimentalDecorators": true, "emitDecoratorMetadata": true } }
内容的提问来源于stack exchange,提问作者Diyan Slavov
相关产品推荐
相关产品推荐

