Typescript mapovanie poľa kľúčov na pole vlastností


Chcel by som urobiť niečo takéto:

type A = { a: string; b: number; c: boolean };
type B = ["b", "a"];

type C = MapProps<A, B> ?? // [number, string]

Najbližšie, čo môžem dosiahnuť, je:

type C = {[key in B[number]]: A[key]}

Ale to vedie k objektu, zatiaľ čo ja by som chcel zahodiť kľúče a len si ponechať hodnoty ako n-ticu, v rovnakom poradí ako B. T.j., existuje niečo ako Object.values() na úrovni typu?

Odpoveď č. 1

Tu budeme musieť použiť rekurzívne podmienené typy. Logika je nasledovná:

V každej iterácii zoberieme prvý prvok (K) z B a uložíme A[K] do nejakého výsledného poľa (R). Pokračujeme, kým B nie je prázdne, a potom vrátime R.

Implementácia :

type MapProps<
  T,
  Keys extends PropertyKey[],
  Result extends unknown[] = []
> = Keys extends [
  infer First extends keyof T,
  ...infer Rest extends PropertyKey[]
]
  ? MapProps<T, Rest, [...Result, T[First]]>
  : Result;

PropertyKey je vstavaný typ pre akýkoľvek kľúč: string | number | symbol.

Na získanie prvého a zvyšných prvkov z typu poľa sme použili kľúčové slovo infer.

Testovanie :

type A = { a: string; b: number; c: boolean };
type B = ["b", "a"];

type C = MapProps<A, B>; // [number, string]

detské ihrisko