Skip to content

Instantly share code, notes, and snippets.

@Alia5
Last active May 17, 2023 08:46
Show Gist options
  • Save Alia5/bc7f1dd772c76736c990ed6993996f22 to your computer and use it in GitHub Desktop.
Save Alia5/bc7f1dd772c76736c990ed6993996f22 to your computer and use it in GitHub Desktop.
Advanced Typescript Cheatsheet
export type Await<T> = T extends PromiseLike<infer U> ? Await<U> : T;
export type IsPromise<T> = PromiseLike<infer U> ? true : false;
export type Length<T> = T extends { length: infer L } ? L : never;
export type KeysOfType<O, T> = {
[K in keyof O]: O[K] extends T ? K : never;
}[keyof O];
// ConvertLiterals would convert literal types like `1337` to their base type like `number` if set to true
export type PickByType<O, T, ConvertLiterals extends boolean = false> = {
[K in KeysOfType<O, T>]: ConvertLiterals extends true ? T : O[K]
};
export type OneOf<T, Strict extends boolean = true> = {
[OuterKey in keyof T]: Strict extends false
? { [K in OuterKey]: T[K] }
: { [InnerKey in OuterKey|keyof T]?: InnerKey extends OuterKey ? T[OuterKey] : never } & { [TheKey in OuterKey]: T[OuterKey] }
}[keyof T];
type Push<T extends unknown[], U> = T extends [...infer R] ? [...T, U] : never;
type PushFront<T extends unknown[], U> = T extends [...infer R] ? [U, ...T] : never;
type Pop<T extends unknown[]> = T extends [...infer R, infer U] ? U : never;
type PopFront<T extends unknown[]> = T extends [infer U, ...infer R] ? U : never;
type Shift<T extends unknown[]> = T extends [infer U, ...infer R] ? R : never;
type ShiftRight<T extends unknown[]> = T extends [...infer R, infer U] ? R : never;
type Reverse<T extends unknown[], U extends unknown[] = []> = Length<T> extends 1 ? Push<U, Pop<T>> : Reverse<ShiftRight<T>, Push<U, Pop<T>>>;
type Filter<T extends unknown[], U> = T extends [] ? [] : T extends [infer F, ...infer R] ? F extends U ? Filter<R, U> : [F, ...Filter<R, U>] : never
type TupleIncludes<T extends unknown[], U> = Length<Filter<T, U>> extends Length<T> ? false : true
type StringIncludes<S extends string, D extends string> = S extends `${infer T}${D}${infer U}` ? true : false;
type Includes<T extends unknown[]|string, U> = T extends unknown[] ? TupleIncludes<T, U> : T extends string ? U extends string ? StringIncludes<T, U> : never : never;
type Split<S extends string, D extends string> =
string extends S ? string[] :
S extends '' ? [] :
S extends `${infer T}${D}${infer U}` ? [T, ...Split<U, D>] : [S];
type Join<T extends unknown[], D extends string> = string[] extends T ? string : T extends string[]
? PopFront<T> extends string ? Length<T> extends 1 ? `${PopFront<T>}` : `${PopFront<T>}${D}${Join<Shift<T>, D>}` : never
: never;
type ValidPaths<T> = keyof T extends never ? never : ({
[K in keyof T]: T[K] extends never ? never : T[K] extends Record<string|number|symbol, unknown>
? K extends string ? `${K}.${ValidPaths<T[K]>}` | K : never
: K
})[keyof T] & string;
type ValidPathTuples<T> = keyof T extends never ? never : ({
[K in keyof T]: T[K] extends never ? never : T[K] extends Record<string|number|symbol, unknown>
? [K, ...ValidPathTuples<T[K]>] | [K]
: [K]
})[keyof T];
type NestedType<T, P extends string> = (
Includes<P, '.'> extends true
? PopFront<Split<P, '.'>> extends keyof T
? NestedType<T[PopFront<Split<P, '.'>>], Join<Shift<Split<P, '.'>>, '.'>>
: never
: P extends keyof T ? T[P] : never
);
type NestedTypeByTuple<T, P extends string[]> = (
Length<P> extends 1
? Pop<P> extends keyof T ? T[Pop<P>] : never
: PopFront<P> extends keyof T ? Shift<P> extends string[]
? NestedTypeByTuple<T[PopFront<P>], Shift<P>>
: never : never
);
type NestedTypeUsingTuplesAgain<T, P extends ValidPaths<T>> = NestedTypeByTuple<T, Split<P, '.'>>;
@Alia5
Copy link
Author

Alia5 commented May 17, 2023

🤔

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