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).

Súvisiace články