Хабр доступен 24/7 благодаря поддержке друзей

Комментарии 3
interface Foo {
[x: string]: unknown;
[x: number]: unknown;
foo: string;
bar: symbol;
}
type Bar = {
[x: number]: number;
[x: symbol]: unknown;
bar: Date;
baz: boolean;
};
export type FooBar = Merge<Foo, Bar>;
// => {
// [x: string]: unknown;
// [x: number]: number;
// [x: symbol]: unknown;
// foo: string;
// bar: Date;
// baz: boolean;
// }Цикл по кортежу, увы, неправильный, там для [A, B, C, D] получается Extend<A, B> & Extend<B, D>, а для [A, B, C] вообще С проигнорируется. Надо поштучно:
type ExtendType<A extends unknown[], R = unknown> = A extends [infer F, ...infer T]
? ExtendType<T, Omit<R, keyof F> & F>
: R;Ну и надо заметить, что это именно extend, а не merge, то есть не всегда то, что может получиться в результате Object.assign({}, a, b, c) или {...a, ...b, ...c}, там всё более хитро, если дело касается опциональных ключей или ключей-индексов.
Вышеупомянутый Merge из type-fest тоже по факту работает как extend, но с некоторыми отличиями и менее правильно, например Merge<{a: number}, {[p: string]: boolean;}> оставляет ключ "a", хотя все ключи надо заменить на boolean
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
TS Extend: полезная утилитарная функция для расширения type