style(skills): standardize utility-types.ts formatting

This commit is contained in:
2026-04-07 08:08:44 -04:00
parent ada8e03a04
commit be389c6cfa

View File

@@ -16,14 +16,14 @@
* type UserId = Brand<string, 'UserId'> * type UserId = Brand<string, 'UserId'>
* type OrderId = Brand<string, 'OrderId'> * type OrderId = Brand<string, 'OrderId'>
*/ */
export type Brand<K, T> = K & { readonly __brand: T } export type Brand<K, T> = K & { readonly __brand: T };
// Branded type constructors // Branded type constructors
export type UserId = Brand<string, 'UserId'> export type UserId = Brand<string, "UserId">;
export type Email = Brand<string, 'Email'> export type Email = Brand<string, "Email">;
export type UUID = Brand<string, 'UUID'> export type UUID = Brand<string, "UUID">;
export type Timestamp = Brand<number, 'Timestamp'> export type Timestamp = Brand<number, "Timestamp">;
export type PositiveNumber = Brand<number, 'PositiveNumber'> export type PositiveNumber = Brand<number, "PositiveNumber">;
// ============================================================================= // =============================================================================
// RESULT TYPE (Error Handling) // RESULT TYPE (Error Handling)
@@ -33,18 +33,18 @@ export type PositiveNumber = Brand<number, 'PositiveNumber'>
* Type-safe error handling without exceptions. * Type-safe error handling without exceptions.
*/ */
export type Result<T, E = Error> = export type Result<T, E = Error> =
| { success: true; data: T } | { success: true; data: T }
| { success: false; error: E } | { success: false; error: E };
export const ok = <T>(data: T): Result<T, never> => ({ export const ok = <T>(data: T): Result<T, never> => ({
success: true, success: true,
data data,
}) });
export const err = <E>(error: E): Result<never, E> => ({ export const err = <E>(error: E): Result<never, E> => ({
success: false, success: false,
error error,
}) });
// ============================================================================= // =============================================================================
// OPTION TYPE (Nullable Handling) // OPTION TYPE (Nullable Handling)
@@ -53,13 +53,13 @@ export const err = <E>(error: E): Result<never, E> => ({
/** /**
* Explicit optional value handling. * Explicit optional value handling.
*/ */
export type Option<T> = Some<T> | None export type Option<T> = Some<T> | None;
export type Some<T> = { type: 'some'; value: T } export type Some<T> = { type: "some"; value: T };
export type None = { type: 'none' } export type None = { type: "none" };
export const some = <T>(value: T): Some<T> => ({ type: 'some', value }) export const some = <T>(value: T): Some<T> => ({ type: "some", value });
export const none: None = { type: 'none' } export const none: None = { type: "none" };
// ============================================================================= // =============================================================================
// DEEP UTILITIES // DEEP UTILITIES
@@ -69,31 +69,31 @@ export const none: None = { type: 'none' }
* Make all properties deeply readonly. * Make all properties deeply readonly.
*/ */
export type DeepReadonly<T> = T extends (...args: any[]) => any export type DeepReadonly<T> = T extends (...args: any[]) => any
? T ? T
: T extends object : T extends object
? { readonly [K in keyof T]: DeepReadonly<T[K]> } ? { readonly [K in keyof T]: DeepReadonly<T[K]> }
: T : T;
/** /**
* Make all properties deeply optional. * Make all properties deeply optional.
*/ */
export type DeepPartial<T> = T extends object export type DeepPartial<T> = T extends object
? { [K in keyof T]?: DeepPartial<T[K]> } ? { [K in keyof T]?: DeepPartial<T[K]> }
: T : T;
/** /**
* Make all properties deeply required. * Make all properties deeply required.
*/ */
export type DeepRequired<T> = T extends object export type DeepRequired<T> = T extends object
? { [K in keyof T]-?: DeepRequired<T[K]> } ? { [K in keyof T]-?: DeepRequired<T[K]> }
: T : T;
/** /**
* Make all properties deeply mutable (remove readonly). * Make all properties deeply mutable (remove readonly).
*/ */
export type DeepMutable<T> = T extends object export type DeepMutable<T> = T extends object
? { -readonly [K in keyof T]: DeepMutable<T[K]> } ? { -readonly [K in keyof T]: DeepMutable<T[K]> }
: T : T;
// ============================================================================= // =============================================================================
// OBJECT UTILITIES // OBJECT UTILITIES
@@ -103,38 +103,40 @@ export type DeepMutable<T> = T extends object
* Get keys of object where value matches type. * Get keys of object where value matches type.
*/ */
export type KeysOfType<T, V> = { export type KeysOfType<T, V> = {
[K in keyof T]: T[K] extends V ? K : never [K in keyof T]: T[K] extends V ? K : never;
}[keyof T] }[keyof T];
/** /**
* Pick properties by value type. * Pick properties by value type.
*/ */
export type PickByType<T, V> = Pick<T, KeysOfType<T, V>> export type PickByType<T, V> = Pick<T, KeysOfType<T, V>>;
/** /**
* Omit properties by value type. * Omit properties by value type.
*/ */
export type OmitByType<T, V> = Omit<T, KeysOfType<T, V>> export type OmitByType<T, V> = Omit<T, KeysOfType<T, V>>;
/** /**
* Make specific keys optional. * Make specific keys optional.
*/ */
export type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>> export type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
/** /**
* Make specific keys required. * Make specific keys required.
*/ */
export type RequiredBy<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>> export type RequiredBy<T, K extends keyof T> = Omit<T, K> &
Required<Pick<T, K>>;
/** /**
* Make specific keys readonly. * Make specific keys readonly.
*/ */
export type ReadonlyBy<T, K extends keyof T> = Omit<T, K> & Readonly<Pick<T, K>> export type ReadonlyBy<T, K extends keyof T> = Omit<T, K> &
Readonly<Pick<T, K>>;
/** /**
* Merge two types (second overrides first). * Merge two types (second overrides first).
*/ */
export type Merge<T, U> = Omit<T, keyof U> & U export type Merge<T, U> = Omit<T, keyof U> & U;
// ============================================================================= // =============================================================================
// ARRAY UTILITIES // ARRAY UTILITIES
@@ -143,30 +145,30 @@ export type Merge<T, U> = Omit<T, keyof U> & U
/** /**
* Get element type from array. * Get element type from array.
*/ */
export type ElementOf<T> = T extends (infer E)[] ? E : never export type ElementOf<T> = T extends (infer E)[] ? E : never;
/** /**
* Tuple of specific length. * Tuple of specific length.
*/ */
export type Tuple<T, N extends number> = N extends N export type Tuple<T, N extends number> = N extends N
? number extends N ? number extends N
? T[] ? T[]
: _TupleOf<T, N, []> : _TupleOf<T, N, []>
: never : never;
type _TupleOf<T, N extends number, R extends unknown[]> = R['length'] extends N type _TupleOf<T, N extends number, R extends unknown[]> = R["length"] extends N
? R ? R
: _TupleOf<T, N, [T, ...R]> : _TupleOf<T, N, [T, ...R]>;
/** /**
* Non-empty array. * Non-empty array.
*/ */
export type NonEmptyArray<T> = [T, ...T[]] export type NonEmptyArray<T> = [T, ...T[]];
/** /**
* At least N elements. * At least N elements.
*/ */
export type AtLeast<T, N extends number> = [...Tuple<T, N>, ...T[]] export type AtLeast<T, N extends number> = [...Tuple<T, N>, ...T[]];
// ============================================================================= // =============================================================================
// FUNCTION UTILITIES // FUNCTION UTILITIES
@@ -175,28 +177,28 @@ export type AtLeast<T, N extends number> = [...Tuple<T, N>, ...T[]]
/** /**
* Get function arguments as tuple. * Get function arguments as tuple.
*/ */
export type Arguments<T> = T extends (...args: infer A) => any ? A : never export type Arguments<T> = T extends (...args: infer A) => any ? A : never;
/** /**
* Get first argument of function. * Get first argument of function.
*/ */
export type FirstArgument<T> = T extends (first: infer F, ...args: any[]) => any export type FirstArgument<T> = T extends (first: infer F, ...args: any[]) => any
? F ? F
: never : never;
/** /**
* Async version of function. * Async version of function.
*/ */
export type AsyncFunction<T extends (...args: any[]) => any> = ( export type AsyncFunction<T extends (...args: any[]) => any> = (
...args: Parameters<T> ...args: Parameters<T>
) => Promise<Awaited<ReturnType<T>>> ) => Promise<Awaited<ReturnType<T>>>;
/** /**
* Promisify return type. * Promisify return type.
*/ */
export type Promisify<T> = T extends (...args: infer A) => infer R export type Promisify<T> = T extends (...args: infer A) => infer R
? (...args: A) => Promise<Awaited<R>> ? (...args: A) => Promise<Awaited<R>>
: never : never;
// ============================================================================= // =============================================================================
// STRING UTILITIES // STRING UTILITIES
@@ -205,31 +207,30 @@ export type Promisify<T> = T extends (...args: infer A) => infer R
/** /**
* Split string by delimiter. * Split string by delimiter.
*/ */
export type Split<S extends string, D extends string> = export type Split<
S extends `${infer T}${D}${infer U}` S extends string,
? [T, ...Split<U, D>] D extends string,
: [S] > = S extends `${infer T}${D}${infer U}` ? [T, ...Split<U, D>] : [S];
/** /**
* Join tuple to string. * Join tuple to string.
*/ */
export type Join<T extends string[], D extends string> = export type Join<T extends string[], D extends string> = T extends []
T extends [] ? ""
? '' : T extends [infer F extends string]
: T extends [infer F extends string] ? F
? F : T extends [infer F extends string, ...infer R extends string[]]
: T extends [infer F extends string, ...infer R extends string[]] ? `${F}${D}${Join<R, D>}`
? `${F}${D}${Join<R, D>}` : never;
: never
/** /**
* Path to nested object. * Path to nested object.
*/ */
export type PathOf<T, K extends keyof T = keyof T> = K extends string export type PathOf<T, K extends keyof T = keyof T> = K extends string
? T[K] extends object ? T[K] extends object
? K | `${K}.${PathOf<T[K]>}` ? K | `${K}.${PathOf<T[K]>}`
: K : K
: never : never;
// ============================================================================= // =============================================================================
// UNION UTILITIES // UNION UTILITIES
@@ -238,27 +239,28 @@ export type PathOf<T, K extends keyof T = keyof T> = K extends string
/** /**
* Last element of union. * Last element of union.
*/ */
export type UnionLast<T> = UnionToIntersection< export type UnionLast<T> =
T extends any ? () => T : never UnionToIntersection<T extends any ? () => T : never> extends () => infer R
> extends () => infer R ? R
? R : never;
: never
/** /**
* Union to intersection. * Union to intersection.
*/ */
export type UnionToIntersection<U> = ( export type UnionToIntersection<U> = (
U extends any ? (k: U) => void : never U extends any
? (k: U) => void
: never
) extends (k: infer I) => void ) extends (k: infer I) => void
? I ? I
: never : never;
/** /**
* Union to tuple. * Union to tuple.
*/ */
export type UnionToTuple<T, L = UnionLast<T>> = [T] extends [never] export type UnionToTuple<T, L = UnionLast<T>> = [T] extends [never]
? [] ? []
: [...UnionToTuple<Exclude<T, L>>, L] : [...UnionToTuple<Exclude<T, L>>, L];
// ============================================================================= // =============================================================================
// VALIDATION UTILITIES // VALIDATION UTILITIES
@@ -268,28 +270,25 @@ export type UnionToTuple<T, L = UnionLast<T>> = [T] extends [never]
* Assert type at compile time. * Assert type at compile time.
*/ */
export type AssertEqual<T, U> = export type AssertEqual<T, U> =
(<V>() => V extends T ? 1 : 2) extends (<V>() => V extends U ? 1 : 2) (<V>() => V extends T ? 1 : 2) extends <V>() => V extends U ? 1 : 2
? true ? true
: false : false;
/** /**
* Ensure type is not never. * Ensure type is not never.
*/ */
export type IsNever<T> = [T] extends [never] ? true : false export type IsNever<T> = [T] extends [never] ? true : false;
/** /**
* Ensure type is any. * Ensure type is any.
*/ */
export type IsAny<T> = 0 extends 1 & T ? true : false export type IsAny<T> = 0 extends 1 & T ? true : false;
/** /**
* Ensure type is unknown. * Ensure type is unknown.
*/ */
export type IsUnknown<T> = IsAny<T> extends true export type IsUnknown<T> =
? false IsAny<T> extends true ? false : unknown extends T ? true : false;
: unknown extends T
? true
: false
// ============================================================================= // =============================================================================
// JSON UTILITIES // JSON UTILITIES
@@ -298,23 +297,23 @@ export type IsUnknown<T> = IsAny<T> extends true
/** /**
* JSON-safe types. * JSON-safe types.
*/ */
export type JsonPrimitive = string | number | boolean | null export type JsonPrimitive = string | number | boolean | null;
export type JsonArray = JsonValue[] export type JsonArray = JsonValue[];
export type JsonObject = { [key: string]: JsonValue } export type JsonObject = { [key: string]: JsonValue };
export type JsonValue = JsonPrimitive | JsonArray | JsonObject export type JsonValue = JsonPrimitive | JsonArray | JsonObject;
/** /**
* Make type JSON-serializable. * Make type JSON-serializable.
*/ */
export type Jsonify<T> = T extends JsonPrimitive export type Jsonify<T> = T extends JsonPrimitive
? T ? T
: T extends undefined | ((...args: any[]) => any) | symbol : T extends undefined | ((...args: any[]) => any) | symbol
? never ? never
: T extends { toJSON(): infer R } : T extends { toJSON(): infer R }
? R ? R
: T extends object : T extends object
? { [K in keyof T]: Jsonify<T[K]> } ? { [K in keyof T]: Jsonify<T[K]> }
: never : never;
// ============================================================================= // =============================================================================
// EXHAUSTIVE CHECK // EXHAUSTIVE CHECK
@@ -324,12 +323,12 @@ export type Jsonify<T> = T extends JsonPrimitive
* Ensure all cases are handled in switch/if. * Ensure all cases are handled in switch/if.
*/ */
export function assertNever(value: never, message?: string): never { export function assertNever(value: never, message?: string): never {
throw new Error(message ?? `Unexpected value: ${value}`) throw new Error(message ?? `Unexpected value: ${value}`);
} }
/** /**
* Exhaustive check without throwing. * Exhaustive check without throwing.
*/ */
export function exhaustiveCheck(_value: never): void { export function exhaustiveCheck(_value: never): void {
// This function should never be called // This function should never be called
} }