Skip to content

Instantly share code, notes, and snippets.

@RubaXa
Created December 20, 2019 11:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RubaXa/4b4b911aac6b8117999f633899e272b7 to your computer and use it in GitHub Desktop.
Save RubaXa/4b4b911aac6b8117999f633899e272b7 to your computer and use it in GitHub Desktop.
type Key = string;
type Val = string | number;
type KeyValue<
K extends Key,
P extends Key, // Дополнительные поля (!)
V extends Val,
> = (
& Record<K, V>
& Record<P, any>
);
type CompostedObject<
KEY extends Key,
F extends string, // Какие поля будет экспортировать как значение
T extends KeyValue<KEY, F, Val>[],
> =
FlattenObject<
ToIntersect<
{
[K in keyof T]: T[K] extends KeyValue<KEY, F, Val>
? Record<T[K][KEY], FlattenObject<Pick<T[K], F>>> // FlattenObject + Pick 💁🏻‍♂️
: never
}[number]
>
>
;
function composeObjects<
K extends Key,
F extends readonly string[], // Фильтр по полям 🎉
T extends KeyValue<K, F[number], string>[],
>(
key: K,
onlyKeys: F,
...objects: T
): CompostedObject<K, F[number], T> {
return objects.reduce((result, obj) => {
result[obj[key] as any] = onlyKeys.reduce((res, key) => {
res[key] = obj[key];
return res;
}, {});
return result;
}, {} as CompostedObject<K, F[number], T>)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment