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

如何使泛型方法装饰器foo适配MethodDecorator类型?

Fixing Generic MethodDecorator Type Compatibility in TypeScript

The error you're encountering stems from a mismatch between your explicit generic constraint and TypeScript's built-in MethodDecorator type signature. Let's break down the issue and fix it properly.

Why the Error Happens

TypeScript defines MethodDecorator as a generic function that works with any type T (representing the decorated method):

type MethodDecorator = <T>(
  target: Object,
  propertyKey: string | symbol,
  descriptor: TypedPropertyDescriptor<T>
) => TypedPropertyDescriptor<T> | void;

Your original code added an explicit T extends Function = Function constraint to the decorator function, which conflicts with MethodDecorator's unconstrained generic T. TypeScript can't reconcile the constrained T in your function with the generic expected by the standard MethodDecorator type.

Solution: Align with MethodDecorator's Generic Signature

You don't need to manually constrain T—since this is a method decorator, TypeScript will automatically infer that T is a function type. Here's the corrected code:

const foo: MethodDecorator = function <T>(
  target: object,
  propertyKey: string | symbol,
  descriptor: TypedPropertyDescriptor<T>
): TypedPropertyDescriptor<T> {
  // Defensive check to ensure we're decorating a method
  if (typeof descriptor.value !== 'function') {
    throw new Error('The foo decorator can only be applied to class methods');
  }

  // Bind the method to null while preserving its original type
  return {
    configurable: true,
    enumerable: false,
    value: descriptor.value.bind(null) as T
  };
};

Key Adjustments:

  • Removed the explicit T extends Function = Function constraint to match MethodDecorator's native generic signature.
  • Added a runtime check to confirm descriptor.value is a function (prevents misuse on non-method properties).
  • Used as T to assert the bound function matches the original method's type—this is safe because bind preserves the function's signature (only overriding the this context to null).

Simplified Version (Without Runtime Check)

If you're certain the decorator will only be used on methods, you can streamline the code with a type assertion:

const foo: MethodDecorator = function <T>(
  target: object,
  propertyKey: string | symbol,
  descriptor: TypedPropertyDescriptor<T>
): TypedPropertyDescriptor<T> {
  const originalMethod = descriptor.value as unknown as Function;
  return {
    configurable: true,
    enumerable: false,
    value: originalMethod.bind(null) as T
  };
};

This works because TypeScript trusts that you're applying the decorator to a method, so T will always be a function type in practice.

内容的提问来源于stack exchange,提问作者Estus Flask

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:32:54