Skip to content

Instantly share code, notes, and snippets.

@gustavoguichard
Created March 23, 2023 03:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gustavoguichard/b3dc866e6728020be3c2e80ec206a190 to your computer and use it in GitHub Desktop.
Save gustavoguichard/b3dc866e6728020be3c2e80ec206a190 to your computer and use it in GitHub Desktop.
Type utilities
type Specify<T> = T extends any ? (k: T) => void : never
// Real intersection: UnionToIntersection<`c${string}` | 'car'> will become `c${string}`
type UnionToIntersection<T> = Specify<T> extends (a: infer A) => void ? A : never;
// Transforms 'a' | 'b' into ((f: "a") => void) & ((f: "b") => void)
type UnionToOverloads<U> = UnionToIntersection<Specify<U>>;
// Still figuring out why this happens
// ((f: "a") => void) & ((f: "b") => void) will become "b"
type LastOfUnion<U> = UnionToOverloads<U> extends (a: infer A) => void ? A : never;
// Only unions won't conform to this
type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : true;
type PopUnion<T> = {
result: LastOfUnion<T>,
rest: Exclude<T, LastOfUnion<T>>
}
// Grabs the last of union as a way to infer last and pops it with exclude
type UnionToTuple<T, output extends unknown[] = []> = IsUnion<T> extends true
? UnionToTuple<PopUnion<T>['rest'], [PopUnion<T>['result'], ...output]>
: [T, ...output];
type ValueOf<Obj> = Obj[keyof Obj];
type Entries<Obj> = {
[K in keyof Obj]: [K, Obj[K]]
}[keyof Obj]
type FromEntries<T extends [string, unknown]> = {
[K in T as K[0]]: K[1]
}
type Compute<T> = { [K in keyof T]: Compute<T[K]> } | never;
type Prettify<T> = {
[K in keyof T]: T[K]
} & {}
type PickByValue<T, Condition> = FromEntries<Extract<Entries<T>, [any, Condition]>>
type OmitByValue<T, Condition> = FromEntries<Exclude<Entries<Extract<T, Record<string, any>>>, [any, Condition]>>
type PickPartial<Obj, Keys> =
Compute<{ [K in Extract<keyof Obj, Keys>]?: Obj[K] }
& { [K in Exclude<keyof Obj, Keys>]: Obj[K] }>
type DeepCamelize<T> =
T extends [any, ...any]
? { [I in keyof T]: DeepCamelize<T[I]> }
: T extends (infer Value)[]
? DeepCamelize<Value>[]
: {
[K in keyof T as SnakeToCamel<K>]: DeepCamelize<T[K]>;
};
type SnakeToCamel<Str> = Str extends `${infer First}_${infer Rest}`
? `${First}${Capitalize<SnakeToCamel<Rest>>}`
: Str;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment