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 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
export type UserId = Brand<string, 'UserId'>
export type Email = Brand<string, 'Email'>
export type UUID = Brand<string, 'UUID'>
export type Timestamp = Brand<number, 'Timestamp'>
export type PositiveNumber = Brand<number, 'PositiveNumber'>
export type UserId = Brand<string, "UserId">;
export type Email = Brand<string, "Email">;
export type UUID = Brand<string, "UUID">;
export type Timestamp = Brand<number, "Timestamp">;
export type PositiveNumber = Brand<number, "PositiveNumber">;
// =============================================================================
// RESULT TYPE (Error Handling)
@@ -34,17 +34,17 @@ export type PositiveNumber = Brand<number, 'PositiveNumber'>
*/
export type Result<T, E = Error> =
| { success: true; data: T }
| { success: false; error: E }
| { success: false; error: E };
export const ok = <T>(data: T): Result<T, never> => ({
success: true,
data
})
data,
});
export const err = <E>(error: E): Result<never, E> => ({
success: false,
error
})
error,
});
// =============================================================================
// OPTION TYPE (Nullable Handling)
@@ -53,13 +53,13 @@ export const err = <E>(error: E): Result<never, E> => ({
/**
* 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 None = { type: 'none' }
export type Some<T> = { type: "some"; value: T };
export type None = { type: "none" };
export const some = <T>(value: T): Some<T> => ({ type: 'some', value })
export const none: None = { type: 'none' }
export const some = <T>(value: T): Some<T> => ({ type: "some", value });
export const none: None = { type: "none" };
// =============================================================================
// DEEP UTILITIES
@@ -72,28 +72,28 @@ export type DeepReadonly<T> = T extends (...args: any[]) => any
? T
: T extends object
? { readonly [K in keyof T]: DeepReadonly<T[K]> }
: T
: T;
/**
* Make all properties deeply optional.
*/
export type DeepPartial<T> = T extends object
? { [K in keyof T]?: DeepPartial<T[K]> }
: T
: T;
/**
* Make all properties deeply required.
*/
export type DeepRequired<T> = T extends object
? { [K in keyof T]-?: DeepRequired<T[K]> }
: T
: T;
/**
* Make all properties deeply mutable (remove readonly).
*/
export type DeepMutable<T> = T extends object
? { -readonly [K in keyof T]: DeepMutable<T[K]> }
: T
: T;
// =============================================================================
// OBJECT UTILITIES
@@ -103,38 +103,40 @@ export type DeepMutable<T> = T extends object
* Get keys of object where value matches type.
*/
export type KeysOfType<T, V> = {
[K in keyof T]: T[K] extends V ? K : never
}[keyof T]
[K in keyof T]: T[K] extends V ? K : never;
}[keyof T];
/**
* 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.
*/
export type OmitByType<T, V> = Omit<T, KeysOfType<T, V>>
export type OmitByType<T, V> = Omit<T, KeysOfType<T, V>>;
/**
* 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.
*/
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.
*/
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).
*/
export type Merge<T, U> = Omit<T, keyof U> & U
export type Merge<T, U> = Omit<T, keyof U> & U;
// =============================================================================
// ARRAY UTILITIES
@@ -143,7 +145,7 @@ export type Merge<T, U> = Omit<T, keyof U> & U
/**
* 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.
@@ -152,21 +154,21 @@ export type Tuple<T, N extends number> = N extends N
? number extends N
? T[]
: _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
: _TupleOf<T, N, [T, ...R]>
: _TupleOf<T, N, [T, ...R]>;
/**
* Non-empty array.
*/
export type NonEmptyArray<T> = [T, ...T[]]
export type NonEmptyArray<T> = [T, ...T[]];
/**
* 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
@@ -175,28 +177,28 @@ export type AtLeast<T, N extends number> = [...Tuple<T, N>, ...T[]]
/**
* 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.
*/
export type FirstArgument<T> = T extends (first: infer F, ...args: any[]) => any
? F
: never
: never;
/**
* Async version of function.
*/
export type AsyncFunction<T extends (...args: any[]) => any> = (
...args: Parameters<T>
) => Promise<Awaited<ReturnType<T>>>
) => Promise<Awaited<ReturnType<T>>>;
/**
* Promisify return type.
*/
export type Promisify<T> = T extends (...args: infer A) => infer R
? (...args: A) => Promise<Awaited<R>>
: never
: never;
// =============================================================================
// STRING UTILITIES
@@ -205,22 +207,21 @@ export type Promisify<T> = T extends (...args: infer A) => infer R
/**
* Split string by delimiter.
*/
export type Split<S extends string, D extends string> =
S extends `${infer T}${D}${infer U}`
? [T, ...Split<U, D>]
: [S]
export type Split<
S extends string,
D extends string,
> = S extends `${infer T}${D}${infer U}` ? [T, ...Split<U, D>] : [S];
/**
* Join tuple to string.
*/
export type Join<T extends string[], D extends string> =
T extends []
? ''
export type Join<T extends string[], D extends string> = T extends []
? ""
: T extends [infer F extends string]
? F
: T extends [infer F extends string, ...infer R extends string[]]
? `${F}${D}${Join<R, D>}`
: never
: never;
/**
* Path to nested object.
@@ -229,7 +230,7 @@ export type PathOf<T, K extends keyof T = keyof T> = K extends string
? T[K] extends object
? K | `${K}.${PathOf<T[K]>}`
: K
: never
: never;
// =============================================================================
// UNION UTILITIES
@@ -238,27 +239,28 @@ export type PathOf<T, K extends keyof T = keyof T> = K extends string
/**
* Last element of union.
*/
export type UnionLast<T> = UnionToIntersection<
T extends any ? () => T : never
> extends () => infer R
export type UnionLast<T> =
UnionToIntersection<T extends any ? () => T : never> extends () => infer R
? R
: never
: never;
/**
* Union to intersection.
*/
export type UnionToIntersection<U> = (
U extends any ? (k: U) => void : never
U extends any
? (k: U) => void
: never
) extends (k: infer I) => void
? I
: never
: never;
/**
* Union to tuple.
*/
export type UnionToTuple<T, L = UnionLast<T>> = [T] extends [never]
? []
: [...UnionToTuple<Exclude<T, L>>, L]
: [...UnionToTuple<Exclude<T, L>>, L];
// =============================================================================
// VALIDATION UTILITIES
@@ -268,28 +270,25 @@ export type UnionToTuple<T, L = UnionLast<T>> = [T] extends [never]
* Assert type at compile time.
*/
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
: false
: false;
/**
* 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.
*/
export type IsAny<T> = 0 extends 1 & T ? true : false
export type IsAny<T> = 0 extends 1 & T ? true : false;
/**
* Ensure type is unknown.
*/
export type IsUnknown<T> = IsAny<T> extends true
? false
: unknown extends T
? true
: false
export type IsUnknown<T> =
IsAny<T> extends true ? false : unknown extends T ? true : false;
// =============================================================================
// JSON UTILITIES
@@ -298,10 +297,10 @@ export type IsUnknown<T> = IsAny<T> extends true
/**
* JSON-safe types.
*/
export type JsonPrimitive = string | number | boolean | null
export type JsonArray = JsonValue[]
export type JsonObject = { [key: string]: JsonValue }
export type JsonValue = JsonPrimitive | JsonArray | JsonObject
export type JsonPrimitive = string | number | boolean | null;
export type JsonArray = JsonValue[];
export type JsonObject = { [key: string]: JsonValue };
export type JsonValue = JsonPrimitive | JsonArray | JsonObject;
/**
* Make type JSON-serializable.
@@ -314,7 +313,7 @@ export type Jsonify<T> = T extends JsonPrimitive
? R
: T extends object
? { [K in keyof T]: Jsonify<T[K]> }
: never
: never;
// =============================================================================
// EXHAUSTIVE CHECK
@@ -324,7 +323,7 @@ export type Jsonify<T> = T extends JsonPrimitive
* Ensure all cases are handled in switch/if.
*/
export function assertNever(value: never, message?: string): never {
throw new Error(message ?? `Unexpected value: ${value}`)
throw new Error(message ?? `Unexpected value: ${value}`);
}
/**