Reputation: 862
There is currently a way to limit the type of property that the given property decorator may be applied to. E.g.
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;
}
But I can't manage to leverage such a type checking for method parameter decorators.
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) {}
}
I can't say for sure why this happens. Is it a TypeScript bug with parameter decorators? Why is there no error message? Is it somehow related to annihilating unit types (e.g. TParamIndex
or TParamName
)?
Upvotes: 2
Views: 233
Reputation: 249506
Your assumption is that TMethodName
and TParamIndex
get inferred to their literal type versions based on usage. They unfortunately don't for parameter decorators (for method decorators the method name does get inferred to the string literal of the method name, so it's at least an inconsistency in the way they are handled).
There is a GitHub issue around this, I even have a version of the typescript compiler code that would do this linked in the issue, but unfortunately it does not seem to be a priority at the moment for the team to incorporate this.
Priorities also change based on feedback, so feel free to upvote the issue, maybe comment about your use case as that will help the team see that there is a real need for this.
Upvotes: 1