Skip to content

Instantly share code, notes, and snippets.

@litera
Last active July 2, 2024 10:55
Show Gist options
  • Save litera/cfaf33d1780290e3094747e4f66791df to your computer and use it in GitHub Desktop.
Save litera/cfaf33d1780290e3094747e4f66791df to your computer and use it in GitHub Desktop.
Typescript useful utility types
type Prefix<TModel extends {}, P extends string> = {
[Key in string & keyof TModel as `${P}${Capitalize<Key>}`]: TModel[Key];
}
type Suffix<TModel extends {}, S extends string> = {
[Key in string & keyof TModel as `${Key}${Capitalize<S>}`]: TMOdel[Key];
}
// EnsureProps<{}> = never
// EnsureProps<Person> = Person
type EnsureProps<TModel> = keyof TModel extends never ? never : TModel;
// copied from https://stackoverflow.com/a/69288824/75642
export type Expand<T> = T extends (...args: infer A) => infer R
? (...args: Expand<A>) => Expand<R>
: T extends infer O
? { [K in keyof O]: O[K] }
: never;
export type ExpandRecursively<T> = T extends (...args: infer A) => infer R
? (...args: ExpandRecursively<A>) => ExpandRecursively<R>
: T extends object
? T extends infer O
? { [K in keyof O]: ExpandRecursively<O[K]> }
: never
: T;
// Use as:
// type SomeExpandedType = Expand<SomeConvolutedType>;
// type SomeFullyExpandedType = ExpandRecursively<SomeConvolutedType>;
// Returns a union of actual enum type values
type EnumValues<TEnum extends string | number> = `${TEnum}` extends `${infer T extends number}`
? T
: `${TEnum}` extends `${infer T extends string}`
? T
: never;
// returns the enum type if it is one or never if it's not ONLY WORKS FOR enumy of "number" sub-type
type IsTsEnum<T> = [T] extends [number] ? ([number] extends [T] ? T : never) : never;
// example usage to map object properties of enum type to some type:
type EnumMap<TModel> = {
[K in keyof TModel]: TModel[K] extends IsTsEnum<TModel[K]> ? EnumValues<TModel[K]> : TModel[K];
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment