ObjectFromEntries
Challenge
Implement the type version of Object.fromEntries
For example:
interface Model {
name: string;
age: number;
locations: string[] | null;
}
type ModelEntries =
| ["name", string]
| ["age", number]
| ["locations", string[] | null];
type result = ObjectFromEntries<ModelEntries>; // expected to be Model
Solution
Zur Lösung dieses Problems können wir wieder einen mapped type erstellen. Wichtig ist es hier, den generischen Typen auf eine Tupel mit zwei Werten zu beschränken:
type ObjectFromEntries<T extends [key: string, value: unknown]> = ...
Nun können wir mit Key in T[0] über alle ersten Elemente aus der Tupel laufen. Nun einfach den Wert T[1] zu verwenden funktioniert nicht, da wir somit alle Typen an der Stelle (z.B. string | number | string[] | null) erhalten. Stattdessen können wir das aktuelle Element aus der Vereinigung mittels Extract herausziehen, und dann den Wert mittels eines Index Type oder Lookup Type erhalten:
type ObjectFromEntries<T extends [key: string, value: unknown]> = {
[key in T[0]]: Extract<T, [key, unknown]>[1];
};