/**
* @description Recursively Constrains a type to only include primitives
*
* // TECH DEBT: Work out if this and SimplifyDeep are both required
*/
export type Const = (A extends Primitive ? A : never) | {
[K in keyof A]: Const;
};
type Primitive = string | number | bigint | boolean;
/**
* @description Removes a string from the start of another string
* @example
* ```ts
* type A = RemoveStart<'a', 'abc'>
* // A is 'bc'
*/
export type RemovePrefix = Subject extends `${Start}${infer End}` ? End : never;
/**
* @description Simplifies a deeply nested object type.
* The resulting type signatures use primitives rather than generics and are easier to read.
* @example
* ```ts
* type A = { a: { b: Partial<{ c: string }> } }
* type B = SimplifyDeep
* // B is { a: { b: { c?: string } } }
* ```
*/
export type SimplifyDeep = Type extends object ? {
[TypeKey in keyof Type]: SimplifyDeep;
} : Type;
/**
* @description Flattens a record of types into a single intersection type
* @example
* ```ts
* type A = {
* 'path/a': { get: { params: { a: string } } },
* 'path/b': { post: { params: { b: number } } },
* 'path/c': { get: { params: { c: string } } }
* }
* type B = Flatten
* // B is {
* get: { params: { a: string } } &
* post: { params: { b: number } } &
* get: { params: { c: string } }
* }
* ```
*/
export type Flatten> = UnionToIntersection;
/**
* @description Converts a union type into an intersection type
* @example
* ```ts
* type A = { a: string } | { b: number }
* type B = UnionToIntersection
* // B is { a: string } & { b: number }
* ```
*/
type UnionToIntersection = (T extends unknown ? (x: T) => unknown : never) extends (x: infer R) => unknown ? R : never;
/**
* @description Checks if a property of an object is optional
* @example
* ```ts
* type A = IsOptional<{ a: string }, 'a'>
* // A is false
* type B = IsOptional<{ a?: string }, 'a'>
* // B is true
* ```
*/
export type IsOptional = K extends keyof T ? T extends Record ? false : true : false;
export {};