如何在TypeScript中获取装饰器修饰方法的参数类型?
TypeScript中获取装饰器修饰方法的参数类型
在TypeScript中,获取装饰器修饰方法的参数类型需要分编译时和运行时两种场景来看:
编译时:直接通过泛型推断或类型工具获取
TypeScript的类型系统在编译阶段可以自动推断方法的参数类型,你定义的泛型装饰器已经实现了这一点——T会被自动推断为ArticleCreated类型,可用于类型层面的操作。
示例代码:
type ArticleCreated = { id: string; content: string }; function Policy<T>( target: Object, key: string | symbol, descriptor: TypedPropertyDescriptor<(event: T) => void> ) { // 编译时,T就是ArticleCreated类型,可用于类型约束、推导等操作 return descriptor; } class ExPolicies { @Policy public onArticleCreated(event: ArticleCreated) { console.log(event); } }
如果需要显式提取参数类型,还可以用TypeScript内置的Parameters工具类型:
// 提取onArticleCreated方法的第一个参数类型 type EventType = Parameters<typeof ExPolicies.prototype.onArticleCreated>[0]; // EventType 等同于 ArticleCreated
运行时:需借助元数据或类构造函数
TypeScript编译为JavaScript后,类型信息会被完全擦除,所以装饰器的运行时函数体内无法直接获取ArticleCreated的类型结构。如果需要在运行时获取类型相关信息,有两种常见方案:
方案1:使用reflect-metadata存储元数据
通过reflect-metadata库可以在编译时将参数的构造函数信息存入元数据,运行时再取出:
import 'reflect-metadata'; // 将ArticleCreated定义为类(而非接口),保留运行时构造函数 class ArticleCreated { id: string; content: string; constructor(id: string, content: string) { this.id = id; this.content = content; } } // 定义元数据键 const PARAM_TYPES_KEY = 'design:paramtypes'; function Policy( target: Object, key: string | symbol, descriptor: TypedPropertyDescriptor<(event: ArticleCreated) => void> ) { // 从元数据中获取参数的构造函数数组 const paramTypes = Reflect.getMetadata(PARAM_TYPES_KEY, target, key); if (paramTypes) { // paramTypes[0]就是ArticleCreated的构造函数 console.log('参数类型名称:', paramTypes[0].name); // 输出 "ArticleCreated" } return descriptor; } class ExPolicies { @Policy public onArticleCreated(event: ArticleCreated) { console.log(event); } }
注意:使用此方案需要在tsconfig.json中开启experimentalDecorators和emitDecoratorMetadata选项。
方案2:直接利用类构造函数判断
如果参数类型是类(而非接口),可以在运行时通过判断参数的constructor属性来识别类型,但这种方式只能判断具体的类实例,无法获取完整的类型结构。
内容的提问来源于stack exchange,提问作者Oreste Viron
相关产品推荐
相关产品推荐

