我正在尝试编写一个泛型类,该类保留一对指向泛型类型键的特殊指针。这是这个 MVP 的playground example
const _idKey = Symbol('_idKey')
const _sortKey = Symbol('_sortKey')
export interface BaseStoreConfig<T, Tid extends keyof T, Tsk extends keyof T | undefined> {
idKey?: Tid
sortKey?: Tsk
}
export class BaseStore<T, Tid extends keyof T & string, Tsk extends keyof T | undefined> {
public [_idKey]: keyof T | 'id'
public [_sortKey]?: keyof T | undefined
constructor({
idKey = 'id', // Errors, see below
sortKey,
}: BaseStoreConfig<T, Tid, Tsk>) {
this[_idKey] = idKey
this[_sortKey] = sortKey
}
}
这会产生一个 ts2322 错误(我已经尝试了 Tid
约束的几种变体,我总是回到这个错误)
Type 'string' is not assignable to type 'Tid'.
'string' is assignable to the constraint of type 'Tid', but 'Tid'
could be instantiated with a different subtype of constraint 'string'.ts(2322)
我通常理解这个错误,但在这种情况下我很困惑。 string
的子类型如何不能分配给这种类型?有没有办法表达这个约束?
答案 0 :(得分:3)
我认为问题在于 Typescript 并不真正支持相同值的不同类型(例如,idKey
),这取决于值是从调用方(Tid
还是 { {1}})或来自实施者(undefined
或 Tid
)。有类似 microsoft/TypeScript#42053 之类的问题作为错误提交,但我不确定何时会得到解决。
您已将构造函数参数注释为 "id"
类型,其 BaseStoreConfig<T, Tid, Tsk>
属性的类型为 idKey
。在尝试为其分配默认值 Tid | undefined
时,编译器将其视为不匹配...因为 "id"
可能无法分配给 "id"
。提到 Tid
而不是专门的 string
的特定错误似乎是自 3.9 之后对 TypeScript 的一些更改(不知道为什么,但我假设它在其他地方做了合理的事情)。如果您恢复到 3.9 and look at it,您将看到明确提及 "id"
的错误。
所以我认为这里的解决方法是不要在解构中使用默认值,因为没有很好的方法来表示相同值的两种不同类型的东西。相反,让我们将默认值移动到构造函数的主体:
"id"
现在一切都编译没有错误。