Typ TypeScriptu člena n-tice závislý od iného
Chcem vytvoriť funkciu, ktorá prijíma mnoho párov objektov a kľúčov týchto objektov a nechám kompilátor, aby to kontroloval. Momentálne som napísal nasledovné:
declare function foo(...params: [any, string][]): void;
Čo mi umožňuje napísať niečo ako
foo([a, "propOfA"], [b, "propOfB"]);
Avšak, umožňuje mi to aj písať
foo([a, "propofB"], [b, "propOfA"]);
Toto dáva zmysel, pretože typ druhej hodnoty je jednoducho string. Môžem použiť keyof na obmedzenie druhej hodnoty každého n-tice, aby bola kľúčom prvej hodnoty tej istej n-tice?
Odpoveď č. 1
Kód v odpovedi @ExplosionPills funguje, ak máte iba jeden argument. Ak chcete podporovať viacnásobné argumenty s hodnotou n-tice, z ktorých každý obmedzuje druhý prvok na kľúč prvého, môžete to urobiť takto:
declare function foo<A extends any[]>(
...params: { [I in keyof A]: [A[I], keyof A[I]] }
): void;
Tu používame mapované n-tice na reprezentáciu params ako funkcie poľa A, a odvodzovanie z mapovaných typov nám umožňuje odhadnúť A z prvého prvku každého argumentu n-tice. Poďme sa uistiť, že to funguje:
const a = { a: 1 };
const b = { b: 2 };
// not allowed
foo([a, "b"]);
foo([b, "a"]);
foo([a, "a"], [b, "a"])
// okay
foo([a, "a"]);
foo([b, "b"]);
foo([a, "a"], [b, "b"]);
Vyzerá to dobre pre mňa. Dúfam, že to pomôže; veľa šťastia!
Odkaz na kód
Odpoveď č. 2
Toto môžete urobiť pomocou generík:
declare function foo<T>(...params: [T, keyof T][]): void;Teraz bude typ T odvodený z prvého prvku poľa argumentu, ktorý zadáte.
const a = { a: 1 }
const b = { b: 2 }
// not allowed
foo([a, 'b']);
foo([b, 'a']);
// okay
foo([a, 'a']);
foo([b, 'b']);
Všimnite si, že ak použijete viac argumentov, napr. foo([a, 'a'], [b, 'b']), a a b musia byť rovnakého typu (alebo kompatibilných typov).
