Redenumește cheia tipului de obiect TypeScript
Am asta:
type Two = {
one: number,
two: string,
three: boolean
}
Vreau să creeze un tip care să arate astfel:
type RenamedTwo = {
one: number,
two: string,
four: boolean // difference
}
Am încercat să-l creez în felul acesta:
type Rename<T, K extends keyof T, N> = Pick<T, Exclude<keyof T, K>> & { [N]: T[K] }
Într-o încercare de a folosi această cale:
type Renamed = Rename<Two, 'three', 'four'>
Dar TSlint marchează [N] ca eroare și oferă acest mesaj de eroare:
[ts] Un nume de proprietate calculat într-un literal de tip trebuie să se refere la o expresie a cărei tip este un tip literal sau un tip 'symbol' unic. [ts] 'N' se referă doar la un tip, dar aici este folosit ca valoare.
Răspuns #1
Trebuie să folosești un tip mapat și pentru proprietatea redenumită:
type Two = {
one: number,
two: string,
three: boolean
}
type Rename<T, K extends keyof T, N extends string> = Pick<T, Exclude<keyof T, K>> & { [P in N]: T[K] }
type Renamed = Rename<Two, 'three', 'four'>
Rețineți că acest lucru nu va funcționa așa cum vă așteptați dacă furnizați mai multe proprietăți:
type Renamed = Rename<Two, 'two' |'three' , 'four' | 'five'> // will be Pick<Two, "one"> & {
// four: string | boolean;
// five: string | boolean;
// }
Răspunsul #2
În versiunea actuală de TypeScript 4.6.2, există o gramatică de remapare pe care o puteți utiliza. Aceasta poate fi implementată mult mai ușor.
PlayGround
type RenameByT<T, U> = {
[K in keyof U as K extends keyof T
? T[K] extends string
? T[K]
: never
: K]: K extends keyof U ? U[K] : never;
};
type Two = { one: number; two: string; three: boolean };
// returnType = { one: number; two: string, four: boolean };
type renameOne = RenameByT<{three: 'four', five: 'nouse'}, Two>;
// returnType = { x: number, y: string, z: boolean; }
type renameAll = RenameByT<{one: 'x', two: 'y', three: 'z'}, Two>;
Tipul RenameByT poate separa în mai multe părți. Explicația este pentru exemplul renameOne
K in keyof Uînseamnă toate cheile dinU. De exemplu, esteone | two | three- Clauza
aspoate fi folosită din ts4.1. Dar nu o pot folosi în 4.4.4, dar pot folosi în 4.6.2. Aceasta se folosește pentru a redenumi KeyKprin tipul condiției K extinde keyof T. keyof T înseamnăthree | five.T[K] extends stringînseamnă căT[K]este string.T['three']este string, așa că returneazăfour,T['five']returneazănouse;- tipul de returnare
K extinde keyof U, astfel încâtT['three']satisface astfel returnează{ four: U['three'] }înseamnă{ four: boolean} - alte taste se întorc la origine
referință:
https://github.com/microsoft/TypeScript/issues/40833 https://www.typescriptlang.org/docs/handbook/2/mapped-types.html
