网站搜索

typescript - 属性装饰器可以定义装饰器属性的类型吗?


我有一个属性装饰器,它返回一个属性描述符。有没有办法通过装饰器告诉编译器被装饰属性x的类型?

例如

// returns a readonly string property descriptor
function d(target, key) {
    return {
        get: function() : string {return 'hello'}
    }
}

// would like type of property x to be `string` either inferred
// or taken from decorator getter signature
class A {
    @d()
    x 
}

我试图解决的问题是为装饰器的用户消除额外的工作——我的装饰器定义了属性(包括类型),所以重复写类型(在这种情况下是 x: string)是多余的。现实中的例子是数据库类,其中所有属性(数百个)都使用了装饰器。目前,每个属性都有装饰器和特定的类型注解。当我启用 --strictNullChecks 时,痛点就出现了,这意味着数百个属性都需要在类型中添加 | null(因为数据库允许将 null 设置为值)。既然装饰器已经决定了属性类型,我希望能够省略类型声明。

我看到 TS 包含一个通用的 TypedPropertyDescriptor 声明,但属性装饰器必须返回 void 或 any,否则编译器会报错。

答案#1

不幸的是,我认为你目前在当前版本的 Typescript 中尝试的操作是不可行的。你正试图通过装饰器隐式设置属性 x 的类型来修改类 A 的签名,编译器无法知道 x 的类型应该是什么,也无法知道 x 应该具有 get 方法。

在 GitHub 上有一个关于类装饰器的非常类似问题的大讨论。https://github.com/Microsoft/TypeScript/issues/4881 如果你感兴趣,可以关注那个讨论帖!

你可以采取不同的方法,为A类提供带约束的泛型;然而,我不确定你想解决的是什么问题,所以这可能不是一个选项。