Snippety

array-prototype-at

const fruits = ['Apple 🍏', 'Banana 🍌', 'Strawberry 🍓', 'Blueberry 🫐'];
// Wybieranie po indexie
✅ fruits.at(0); // Apple 🍏
✅ fruits.at(3); // Blueberry 🫐
// Przedostatni element
❌ fruits[fruits.length - 2]; // Strawberry 🍓
❌ fruits.slice(-2, -1)[0]; // Strawberry 🍓
✅ fruits.at(-2); // Strawberry 🍓

image-set.css

.box {
background-image: url("large-balloons.jpg");
background-image: image-set(
url("large-balloons.avif") type("image/avif"),
url("large-balloons.jpg") type("image/jpeg"));
}

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!

Frontlive School

Wyróżnij się na rynku pracy, nie wydając ani złotówki!

Wchodzę

Dołącz do społeczności!

Bo w programowaniu liczą się ludzie

Wchodzę