Skip to content

Instantly share code, notes, and snippets.

@demipixel
Created July 1, 2022 23:02
Show Gist options
  • Save demipixel/b14a6981dff823fda2ba1f1879d1446f to your computer and use it in GitHub Desktop.
Save demipixel/b14a6981dff823fda2ba1f1879d1446f to your computer and use it in GitHub Desktop.
type FilterOut =
| string
| number
| Date
| undefined
| null
// eslint-disable-next-line @typescript-eslint/ban-types
| Function
| FilterOut[];
type FlattenIfArr<T> = T extends (infer R)[] ? R : T;
type FilterKeys<T> = {
[K in keyof T]: T[K] extends FilterOut ? never : K;
}[keyof T];
export type Depth<T> = Partial<
{ [K in FilterKeys<T>]: Depth<NonNullable<FlattenIfArr<T[K]>>> }
>;
type KeysOf<T> = { [K in keyof T]: K }[keyof T];
type CondNullable<T, U> = T extends null ? U | null : U;
type MakeRequiredRecursive<T, S> = T extends FilterOut ? T : {
[K in keyof S]-?: K extends keyof T
? T[K] extends (infer R)[] | undefined
? (Omit<NonNullable<R>, KeysOf<S[K]>> & MakeRequiredRecursive<R, S[K]>)[]
: CondNullable<
T[K],
Omit<NonNullable<T[K]>, KeysOf<S[K]>> &
MakeRequiredRecursive<NonNullable<T[K]>, S[K]>
>
: never;
};
export type MakeRequired<T extends object, U extends Depth<T>> = CondNullable<
T,
Omit<T, KeysOf<U>>
> &
MakeRequiredRecursive<NonNullable<T>, U>;
@demipixel
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment