So, i'm working on some typescript code and i found this weird bug that i don't know why it happens. I'm just starting with the language so it might be a newbie question but anyway, this is really strange to me.
First thing first i have a typescript playground so you guys can iterate on it to help me on solving it
Anyway, so here is the code i'm working on, just an example:
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
}
As i was debugging i saw that ModelIndex
actually is passed as ModelIndex<M & Model>
but this is not what i want, what i want is ModelIndex<M>
, i don't know and i don't understand why typescript does this automatic intersection.
Thanks a lot in advance