目前有一种方法可以限制给定属性装饰器可以应用的属性类型。例如。
type PropertyDecorator<TPropType = unknown> = (
<
TPropName extends string | symbol,
TProtoOrClass extends Record<TPropName, TPropType>
>
(protoOrClass: TProtoOrClass, propName: TPropName) => void
);
function boolPropertyDecorator(): PropertyDecorator<boolean> {
return () => {};
}
class Foo {
// compile-time error "Type 'number' is not assignable to type 'boolean'"
@boolPropertyDecorator()
prop!: number;
}
但我无法利用这种类型检查方法参数装饰器。
type ParameterDecorator<TParamType = unknown> = (
<
TMethodName extends string | symbol,
TParamIndex extends number,
TProtoOrClass extends Record<
TMethodName,
(this: TProtoOrClass, ...args: unknown[] & Record<TParamIndex, TParamType>) => unknown
>
>
(
protoOrClass: TProtoOrClass,
methodName: TMethodName,
parameterIndex: TParamIndex
) => void
);
function numberParameterDecorator(): ParameterDecorator<number> {
return () => {};
}
class Foo {
// no decorator-related error message is generated, but should!
method(@numberParameterDecorator() str: string) {}
}
我不能肯定地说为什么会这样。它是带参数装饰器的TypeScript错误吗?为什么没有错误消息?它是否与消灭单位类型(例如TParamIndex
或TParamName
)有某种关系?
您的假设是TMethodName
和TParamIndex
根据用法推断出它们的文字类型版本。遗憾的是,它们不适用于参数装饰器(对于方法装饰器,方法名称确实被推断为方法名称的字符串文字,因此它们的处理方式至少是不一致的)。
围绕这个问题有一个GitHub issue,我甚至有一个打字稿编译器代码的版本,可以在问题中进行链接,但不幸的是,目前团队合并这个并不是优先事项。
优先级也会根据反馈进行更改,因此请随意提出问题,或者对您的用例进行评论,因为这将有助于团队确定真正需要这样做。