如何限制给定参数修饰符可以应用于的参数类型

时间:2019-03-13 14:27:01

标签: typescript compiler-errors decorator typescript-generics typescript-decorator

当前有一种方法可以限制可以应用给定属性装饰器的属性的类型。例如

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错误吗?为什么没有错误信息?它与消灭单位类型(例如TParamIndexTParamName)有某种联系吗?

1 个答案:

答案 0 :(得分:1)

您的假设是,TMethodNameTParamIndex根据使用情况推断出其文字类型版本。不幸的是,它们不是用于参数修饰符的(对于方法修饰符,方法名的确会推断为方法名的字符串文字,因此,至少在处理它们的方式上不一致)。

这周围有一个GitHub issue,我什至有一个版本的打字稿编译器代码可以解决这个问题,但是不幸的是,目前看来,这并不是团队优先考虑的事情。合并这个。

优先级也会根据反馈而变化,因此可以随时提出意见,也许对您的用例发表评论,因为这将帮助团队看到确实有此需要。