@magnetarjs/types
Version:
Magnetar shared types
40 lines (39 loc) • 1.84 kB
TypeScript
import { EqualsAnyOfUnion, IsFullStringLiteral } from './Equals.js';
/**
* Joins two keys into a dot notation path
*
* Stops at arrays. Otherwise it would include `${number}`
*/
type Join<K, P> = K extends string ? P extends string ? IsFullStringLiteral<P> extends true ? `${K}.${P}` : K : P extends number ? K : never : never;
type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...0[]];
/**
* All possible Object Paths, branches AND leaves — does NOT go deeper in optional props
* @example OPathsWithoutOptional<{ a: { b: number }, x?: { y?: number } }>
* // returns 'a' | 'a.b' | 'x'
*/
export type OPathsWithoutOptional<T, D extends number = 10> = [D] extends [never] ? never : EqualsAnyOfUnion<T, null | undefined> extends 1 ? '' : T extends {
[key: string]: any;
} ? {
[K in keyof T]-?: K extends string ? `${K}` | Join<K, OPathsWithoutOptional<T[K], Prev[D]>> : never;
}[keyof T] : '';
/**
* All possible Object Paths, branches AND leaves— DOES go deeper in optional props
* @example OPathsWithOptional<{ a: { b: number }, x?: { y?: number } }>
* // returns 'a' | 'a.b' | 'x' | 'x.y'
*/
export type OPathsWithOptional<T, D extends number = 10> = [D] extends [never] ? never : T extends {
[key: string]: any;
} ? Exclude<{
[K in keyof T]: K extends string ? `${K}` | Join<K, OPathsWithOptional<T[K], Prev[D]>> : never;
}[keyof T], undefined> : '';
/**
* All possible Object Paths, but only the leaves
* @example OPaths<{ a: { b: number } }>
* // returns 'a.b'
*/
export type OLeaves<T, D extends number = 10> = [D] extends [never] ? '' : EqualsAnyOfUnion<T, null | undefined> extends 1 ? '' : T extends {
[key: string]: any;
} ? {
[K in keyof T]-?: IsFullStringLiteral<K> extends true ? Join<K, OLeaves<T[K], Prev[D]>> : '';
}[keyof T] : '';
export {};