UNPKG

type-plus

Version:
204 lines (201 loc) 4.63 kB
/* eslint-disable @typescript-eslint/no-unsafe-assignment */ import type { AnyRecord } from './AnyRecord.js' import type { Omit } from './omit.js' import { reduceByKey } from './reduceKey.js' import type { Partial } from './Partial.js' import type { NonUndefined } from '../utils/NonUndefined.js' type Splitter<T extends AnyRecord> = Partial<{ [k in keyof T]: T[k] | undefined }> export type Split<T extends AnyRecord, S extends AnyRecord> = { [k in keyof S]-?: S[k] extends undefined ? T[k] : NonNullable<T[k]> | NonUndefined<S[k]> } /** * Split an object into multiple objects. * @returns [...entries, remaining] */ export function split<T extends AnyRecord, S1 extends Splitter<T>>( target: T, split1: S1 ): [Split<T, S1>, Omit<T, keyof S1>] export function split<T extends AnyRecord, S1 extends Splitter<T>, S2 extends Splitter<T>>( target: T, split1: S1, split2: S2 ): [Split<T, S1>, Split<T, S2>, Omit<T, keyof S1 | keyof S2>] export function split< T extends AnyRecord, S1 extends Splitter<T>, S2 extends Splitter<T>, S3 extends Splitter<T> >( target: T, splitter1: S1, splitter2: S2, splitter3: S3 ): [Split<T, S1>, Split<T, S2>, Split<T, S3>, Omit<T, keyof S1 | keyof S2 | keyof S3>] export function split< T extends AnyRecord, S1 extends Splitter<T>, S2 extends Splitter<T>, S3 extends Splitter<T>, S4 extends Splitter<T> >( target: T, splitter1: S1, splitter2: S2, splitter3: S3, splitter4: S4 ): [ Split<T, S1>, Split<T, S2>, Split<T, S3>, Split<T, S4>, Omit<T, keyof S1 | keyof S2 | keyof S3 | keyof S4> ] export function split< T extends AnyRecord, S1 extends Splitter<T>, S2 extends Splitter<T>, S3 extends Splitter<T>, S4 extends Splitter<T>, S5 extends Splitter<T> >( target: T, splitter1: S1, splitter2: S2, splitter3: S3, splitter4: S4, splitter5: S5 ): [ Split<T, S1>, Split<T, S2>, Split<T, S3>, Split<T, S4>, Split<T, S5>, Omit<T, keyof S1 | keyof S2 | keyof S3 | keyof S4 | keyof S5> ] export function split< T extends AnyRecord, S1 extends Splitter<T>, S2 extends Splitter<T>, S3 extends Splitter<T>, S4 extends Splitter<T>, S5 extends Splitter<T>, S6 extends Splitter<T> >( target: T, splitter1: S1, splitter2: S2, splitter3: S3, splitter4: S4, splitter5: S5, splitter6: S6 ): [ Split<T, S1>, Split<T, S2>, Split<T, S3>, Split<T, S4>, Split<T, S5>, Split<T, S6>, Omit<T, keyof S1 | keyof S2 | keyof S3 | keyof S4 | keyof S5 | keyof S6> ] export function split< T extends AnyRecord, S1 extends Splitter<T>, S2 extends Splitter<T>, S3 extends Splitter<T>, S4 extends Splitter<T>, S5 extends Splitter<T>, S6 extends Splitter<T>, S7 extends Splitter<T> >( target: T, splitter1: S1, splitter2: S2, splitter3: S3, splitter4: S4, splitter5: S5, splitter6: S6, splitter7: S7 ): [ Split<T, S1>, Split<T, S2>, Split<T, S3>, Split<T, S4>, Split<T, S5>, Split<T, S6>, Split<T, S7>, Omit<T, keyof S1 | keyof S2 | keyof S3 | keyof S4 | keyof S5 | keyof S6 | keyof S7> ] export function split< T extends AnyRecord, S1 extends Splitter<T>, S2 extends Splitter<T>, S3 extends Splitter<T>, S4 extends Splitter<T>, S5 extends Splitter<T>, S6 extends Splitter<T>, S7 extends Splitter<T>, S8 extends Splitter<T> >( target: T, splitter1: S1, splitter2: S2, splitter3: S3, splitter4: S4, splitter5: S5, splitter6: S6, splitter7: S7, splitter8: S8 ): [ Split<T, S1>, Split<T, S2>, Split<T, S3>, Split<T, S4>, Split<T, S5>, Split<T, S6>, Split<T, S7>, Split<T, S8>, Omit<T, keyof S1 | keyof S2 | keyof S3 | keyof S4 | keyof S5 | keyof S6 | keyof S7 | keyof S8> ] export function split< T extends AnyRecord, S1 extends Splitter<T>, S2 extends Splitter<T>, S3 extends Splitter<T>, S4 extends Splitter<T>, S5 extends Splitter<T>, S6 extends Splitter<T>, S7 extends Splitter<T>, S8 extends Splitter<T>, S9 extends Splitter<T> >( target: T, splitter1: S1, splitter2: S2, splitter3: S3, splitter4: S4, splitter5: S5, splitter6: S6, splitter7: S7, splitter8: S8, splitter9: S9 ): [ Split<T, S1>, Split<T, S2>, Split<T, S3>, Split<T, S4>, Split<T, S5>, Split<T, S6>, Split<T, S7>, Split<T, S8>, Split<T, S9>, Omit<T, keyof S1 | keyof S2 | keyof S3 | keyof S4 | keyof S5 | keyof S6 | keyof S7 | keyof S8 | keyof S9> ] export function split(target: AnyRecord, ...splitters: AnyRecord[]): AnyRecord[] { const keyMap: AnyRecord = {} const s = splitters.map(s => reduceByKey(s, (p, k) => ((keyMap[k] = true), (p[k] = target[k] ?? s[k]), p), {} as AnyRecord) ) const r = reduceByKey(target, (p, k) => (keyMap[k] ? p : ((p[k] = target[k]), p)), {} as AnyRecord) return [...s, r] }