You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 01:57:28