Kolejna ciekawa sztuczka z operatorem keyof, jaką poznamy. Myślę, że lekcja będzie ciekawa, choć krótka. Zaczynajmy.
Ok, więc taki obiekcik sobie tworzymy a w zasadzie typ:
type WithDepArr = {
name: string;
age: number;
dependencyArr? : (keyof WithDepArr)[];
}
Teraz korzystamy z tego, co mamy:
let obj32: WithDepArr = {
name: "John",
age: 23,
dependencyArr: ['name', 'age'],
}
No jak widać ciekawie. Nie możemy podać czegoś, co nie jest kluczem. Ok, ale co z index types?
type WithDepArr2 = {
[K: string] : any;
dependencyArr? : (keyof WithDepArr2)[];
};
let obj322: WithDepArr2 = {
name: "John",
age: 23,
cash: 1000,
dependencyArr: ['namee', 'cash', 'blabla'],
}
Tu jak widać błędu nie ma. Bo wnioskowanie idzie po typie, to znaczy każdy string jest ok. Number by nie przeszedł, każdy string jest valid.
Ok, spróbujmy to sobie jakoś rozłożyć:
type StringKeyObj = {
[K: string]: any;
}
let someJane: StringKeyObj = {
name: "Jane",
lastName: "Doe",
age: 22
};
Teraz zrobimy nasze utility:
type WithDepArr<T> = {
[P in keyof T]: T[P];
} & {
dependencyArr: (keyof T)[];
}
Ok, dalej kombinujemy:
type WithDepArr<T> = {
[P in keyof T]: T[P];
} & {
dependencyArr: (keyof T)[];
}
type JaneWithDependency = WithDepArr<typeof someJane>;
let someJaneDeps: JaneWithDependency = {
name: "Jane",
lastName: "Doe",
age: 22,
dependencyArr: ['name', 1, 'age', 'agee']
};
I dalej nie działa. Trudno. Przynajmniej poznaliśmy index types. Być może wymyślimy z czasem sposób, aby działało, tak czy inaczej poznaliśmy fajne zastosowanie operatora keyof, ale jak widać te typy z dynamicznymi indeksami potrafią dużo zepsuć.
Pytanie otwarte, czy opłaca się takich typów używać.