typescript - Declară o variabilă, având o cheie care este o concatenare a două tipuri
Aș dori să blochez crearea unui obiect declarând că cheile din acesta sunt concatenarea a două tipuri. Deoarece este neclar, permiteți-mi să îl ilustrez cu ceva cod :
type Letter = 'A' | 'B' | 'C';
boxes: { [ID in Letter]: string }[] = ...;
Chiar acum, acest cod permite crearea unui set de cutii astfel :
boxes = [{ A: 1 }]; // Correct
boxes = [{ D: 1 }]; // Incorrect
Ceea ce aș dori să realizez este să fac același lucru, dar să încorporez cifre în chei. Ceva de genul acesta :
type Letter = 'A' | 'B' | 'C';
type Digit = '0' | '1' | '2';
boxes: { [ID in (Letter + '-' + Digit)]: string }[] = ...;
Unde un utilizator ar putea apoi să creeze acest lucru
boxes = { 'A-1': 1 };
Este posibil și, dacă da, cum?
PS: cheile trebuie să fie dinamice, adică nu pot să declar un tip nou format din toate combinațiile posibile
Răspuns #1
Șirul A-1 necesită evaluarea (Letter + '-' + Digit) la rulare. Este imposibil să se obțină siguranță de tip pentru astfel de chei în TypeScript.
Dacă siguranța tipurilor este o cerință, cheile precum A-1 nu pot fi considerate o metodă adecvată.
Răspunsul #2
Nu, acest lucru nu este posibil, nu există suport pentru manipularea literelor de tip șir.
Dacă setul tău de șiruri este limitat (așa cum este în exemplul oferit), atunci cea mai bună opțiune este să generezi toate combinațiile (nu ar trebui să fie foarte multe și ai putea scrie un script pentru a le genera)
Dacă ai multe combinații posibile, atunci s-ar putea să fie mai bine să folosești doar o semnătură de index simplă.
O altă abordare este să redefiniți structura de date într-un mod în care a doua parte a indexului este de fapt un obiect imbricat, este mai detaliat, dar sigur din punct de vedere al tipurilor:
type Letter = 'A' | 'B' | 'C';
type Digit = '0' | '1' | '2';
type UnionOfJustOneProperty<T extends string, TAll extends string> = T extends string ? { [P in T]: string } & { [P in Exclude<TAll, T>]?: never }: never;
let boxes: { [P in Letter]: UnionOfJustOneProperty<Digit,Digit> }[] = [
{
A: { "0": "value"},
B: { "1": "value"},
C: { "0": "value", /* "1": "" */} // the commented code causes an error, we can only have one key in the object
}
];
