所以,我正在研究一些typescript代码,我发现了这个奇怪的bug,我不知道为什么会发生。我刚开始学习语言,所以这可能是一个新手问题,但无论如何,这对我来说真的很奇怪。
首先,我有一个typescript playground所以你们可以迭代它来帮助我解决它
无论如何,这是我正在处理的代码,只是一个例子:
class Model {
fields!: ModelFields;
options!: ModelOptions<this>;
}
class ModelWithoutIndex {
fields!: ModelFields;
options!: ModelOptionsWithoutIndex<this>;
}
class ModelWithIndexNotInBrackets {
fields!: ModelFields;
options!: ModelOptionsNotInBracket<this>;
}
class User extends Model {
fields = {
a: FieldTypes.BOOL
}
// V - Why? and how to solve it?
options: ModelOptions<this> = {
indexes: [{
unique: true,
fields: ['a']
}]
}
}
class UserWithoutIndex extends ModelWithoutIndex {
fields = {
a: FieldTypes.BOOL
}
// V - This works, why???? You know what's strange, it just don't work because ModelIndex is an Object defined in {}
options: ModelOptionsWithoutIndex<this> = {
}
}
class UserWithIndexNotInBrackets extends ModelWithIndexNotInBrackets {
fields = {
a: FieldTypes.BOOL
}
// V - As i said, why this works?, This doesn't make sense to me
options: ModelOptionsNotInBracket<this> = {
}
}
// ------------ TYPES ----------------
enum FieldTypes {
CHAR = 'CHAR',
BOOL = 'BOOL',
INT = 'INT'
}
type ModelIndex<M extends Model> = {
unique: true
fields: (keyof M["fields"])[]
}
type ModelIndexesNotInBracket<M extends ModelWithIndexNotInBrackets> = (keyof M["fields"])[]
type OrderingOfModelOptions<M extends Model | ModelWithoutIndex | ModelWithIndexNotInBrackets> = keyof M["fields"]|
keyof { [F in keyof M["fields"] as F extends string ? `-${F}` : never] : 1}
type ModelOptionsNotInBracket<M extends ModelWithIndexNotInBrackets> = {
indexes?: ModelIndexesNotInBracket<M>[];
ordering?: OrderingOfModelOptions<M>[];
}
type ModelOptionsWithoutIndex<M extends ModelWithoutIndex> = {
ordering?: OrderingOfModelOptions<M>[];
}
type ModelOptions<M extends Model> = {
indexes?: ModelIndex<M>[];
ordering?: OrderingOfModelOptions<M>[];
}
type ModelFields = {
[field: string]: FieldTypes
}
当我在调试时,我看到ModelIndex
实际上被传递为ModelIndex<M & Model>
,但这不是我想要的,我想要的是ModelIndex<M>
,我不知道,我不明白为什么typescript会自动交叉。
Thanks much in advance
我提交了一个问题,他们回应了我,类型不会在类属性初始化器上自动断言。你可以在这里看到答案,但我也会为其他人翻译
您的属性字段具有类型
{ a: FieldTypes }
,但是您的泛型ModelOptions<>
需要类型参数来扩展Model
。但是this
的类型是{ fields: { a: FieldTypes } }
,它不扩展Model
(即{ fields: ModelFields; options: ModelOptions<this> }
)。
当你正确输入属性字段时,它会工作:
class User extends Model {
fields: ModelFields = {
a: FieldTypes.BOOL
}
// ...
}
重新定义的属性类型不被继承。这将需要#10570。