Snippety

assert.ts

function assert<T>(
condition: T,
message,
): asserts condition is Exclude<T, null | undefined> {
if (condition === null || condition === undefined) {
throw new Error(message);
}
}

recursive.ts

Recursive<T>

type Recurse<T> =
T extends { __rec: unknown }
? Recurse<_Recurse<T>>
: T;
type _Recurse<T> =
T extends { __rec: never } ? never
: T extends { __rec: { __rec: infer U } } ? { __rec: _Recurse<U> }
: T extends { __rec: infer U } ? U
: T;
type Repeat<T, N extends number> = Recurse<_Repeat<T, N, []>>;
type _Repeat<T, N extends number, A extends T[]> =
A["length"] extends N
? A
: { __rec: _Repeat<T, N, [T, ...A]> };
// XS = ["x", ..., "x"] and XS["length"] = 100
type XS = Repeat<'aaa', 5>;

camelize.ts

Turn your snake_case into camelCase (works for strings and objects)

// Usage: type CamelCase = CamelizeString<'snake_case'> -> snakeCase
export type CamelizeString<Value> =
Value extends string ?
Value extends `${infer T}_${infer U}` ?
`${T}${Capitalize<CamelizeString<U>>}` :
Value : Value
type KeyOf<Object extends Record<string, unknown>> = Extract<keyof Object, string>;
// Usage: type CamelCaseObject = CamelizeObject<{my_name: string}>; -> {myName: string}
export type CamelizeObject<Object extends Record<KeyOf<Object>, unknown>> = {[Key in KeyOf<Object> as CamelizeString<Key>]: Object[Key]}
export type CamelizeObjectDeep<Value> = Value extends Function
? Value
: Value extends Array<infer U>
? Array<CamelizeObjectDeep<U>>
: Value extends Set<infer U>
? Set<CamelizeObjectDeep<U>> : {
[K in keyof Value as CamelizeString<K>]: CamelizeObjectDeep<Value[K]>;
};

parse-route-parameters.ts

TypeScript - parse route parameters

type ParseRouteParameters<Route> = Route extends `${string}/:${infer Param}/${infer Rest}`
? { [Entry in Param | keyof ParseRouteParameters<`/${Rest}`>]: string }
: Route extends `${string}/:${infer Param}`
? { [Entry in Param]: string }
: {};
type X = ParseRouteParameters<'/api/:what/:is/notyou/:happening'>;
// type X = {
// what: string,
// is: string,
// happening: string,
// }

tuple-to-union-type.ts

TypeScript - tuple to union type

type UnionFromTuple<Tuple extends readonly (string | number | boolean)[]> = Tuple[number];
const animals = ['🦙', '🦑', '🐍', '🦘'] as const;
type Animal = UnionFromTuple<typeof animals>;
// type Animal = '🦙' | '🦑' | '🐍' | '🦘'

O autorze

Olaf Sulich

Olaf jest Frontend Developerem, blogerem i nosi rybacki kapelusz 🎩 Pisze o wszystkim co związane z frontendem, ale nie boi się backendu i designów 🦾 Ma głowę pełną pomysłów i nadzieję, że znajdziesz tutaj coś dla siebie!