Skip to content

Instantly share code, notes, and snippets.

@lukasbach
Last active March 23, 2022 21:49
Show Gist options
  • Save lukasbach/fb1024fea775582ee502d2f5cc5500ce to your computer and use it in GitHub Desktop.
Save lukasbach/fb1024fea775582ee502d2f5cc5500ce to your computer and use it in GitHub Desktop.
TypeScript Advanced typing recipes
type Wrapper<T> = { wrapped: T };
type MapObject<T extends Record<keyof Object, any>> = {
[K in keyof T]: Wrapper<T[K]>;
};
type MapTuple<T extends [...any[]]> = {
[I in keyof T]: Wrapper<T[I]>;
} & { length: T["length"] };
type MapObject<T extends Record<keyof Object>;
export type Flatten<
Arr extends ReadonlyArray<unknown>,
Result extends ReadonlyArray<unknown> = []
> =
// if Arr is empty -> return Result
Arr extends readonly []
? Result
: // if Arr is not empty - destruct it
Arr extends readonly [infer Head, ...infer Tail]
? // check if Head is an Array
Head extends ReadonlyArray<any>
? // if it is -> call Reducer with flat Head and Tail
Flatten<readonly [...Head, ...Tail], Result>
: // otherwise call Reducer with Head without flattening
Flatten<Tail, readonly [...Result, Head]>
: never;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment