TypeScript中NestJS自定义Acl装饰器类型报错问题及解决
NestJS自定义装饰器TS2536错误分析与解决
问题根源
这段代码的核心问题是类型推断偏差:
policyInstance被TypeScript默认推断为父类PermissionPolicy类型,但实际它是子类(如AuthPolicy)的实例TActions约束为子类实例的键集合(keyof InstanceType<TPolicyClass>),用这些键去索引被推断为父类类型的policyInstance时,TypeScript判定父类可能不存在这些键,因此抛出TS2536错误- 类型断言只是强制跳过类型检查,并未从根源解决类型不匹配的问题
正确解决方法
显式指定policyInstance的类型为子类实例类型(InstanceType<TPolicyClass>),让TypeScript明确该实例拥有子类的所有属性:
import { SetMetadata } from '@nestjs/common'; import { PermissionPolicy } from '../permission.policy'; type ClassThatExtends<TClass = any> = new (...args) => TClass; // Check if user has provided permission to access this route export const Acl = < TPolicyClass extends ClassThatExtends<PermissionPolicy>, TActions extends (keyof InstanceType<TPolicyClass>)[], >( policyClass: TPolicyClass, actions: TActions, ) => { // 显式指定实例类型为子类实例 const policyInstance: InstanceType<TPolicyClass> = new policyClass(); const requiredPermissions = actions.reduce((acc, actionName) => { return [...acc, ...policyInstance[actionName]]; }, [] as string[]); return SetMetadata('aclPermissions', requiredPermissions); };
修改后,TypeScript能正确识别actionName是policyInstance的合法键,无需类型断言即可通过类型检查,同时保留了完整的类型安全性。
内容的提问来源于stack exchange,提问作者Md. A. A. Apu
相关产品推荐
相关产品推荐

