All files / src/types Flattable.ts

100% Statements 14/14
100% Branches 16/16
100% Functions 4/4
100% Lines 12/12

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 301x             1x                   1x 68x 14x 54x 47x 7x 9x 2x 3x 1x      
import { mapRecord } from '../utils';
 
export interface Flattable<Flatten> {
 
    flatten: Flatten;
}
 
export namespace Flattable {
 
    export type Flatten<T> =
        T extends Flattable<infer U> ? Flatten<U> :
            T extends undefined | null | boolean | number | bigint | string | Uint8Array ? T :
                T extends [infer U, ...(infer V)] ? [Flatten<U>, ...Flatten<V>] :
                    T extends (infer U)[] ? Flatten<U>[] :
                        T extends Record<string, unknown> ? { [K in keyof T]: Flatten<T[K]> } :
                            T;
 
    export function flatten<T>(value: T): Flatten<T> {
        if (typeof value === 'object' && value !== null && 'flatten' in value)
            return flatten(value.flatten) as Flatten<T>;
        if (typeof value === 'undefined' || value === null || typeof value === 'boolean' || typeof value === 'number' || typeof value === 'bigint' || typeof value === 'string' || value instanceof Uint8Array)
            return value as Flatten<T>;
        if (Array.isArray(value))
            return value.map(element => flatten(element)) as Flatten<T>;
        if (typeof value === 'object')
            return mapRecord(value as Record<PropertyKey, unknown>, value => flatten(value)) as Flatten<T>;
        return value as Flatten<T>;
    }
}