Skip to content

Commit

Permalink
feat: add some comments for types
Browse files Browse the repository at this point in the history
  • Loading branch information
kakasoo committed Jan 20, 2025
1 parent 665e429 commit 3cc8c88
Show file tree
Hide file tree
Showing 12 changed files with 134 additions and 25 deletions.
7 changes: 7 additions & 0 deletions src/types/DeepDateToString.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
/**
* A utility type that recursively converts all `Date` types within a nested object or array to `string`.
*
* - If `T` is an array of objects, the type processes each element recursively.
* - If `T` is a `Date`, it is converted to `string`.
* - If `T` is an object, each key is checked recursively for `Date` types or nested objects.
*/
export type DeepDateToString<T> =
T extends Array<infer I extends object>
? Array<DeepDateToString<I>>
Expand Down
7 changes: 4 additions & 3 deletions src/types/DeepStrictObjectKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ type __DeepStrictObjectKeys<
: never;

/**
* @title 중첩된 객체 혹은 배열의 모든 키를 표기하는 타입.
* @title Type for Listing All Keys of Nested Objects or Arrays.
*
* 중첩된 객체의 모든 키를 뽑는 타입으로, 만약 중첩된 객체가 있을 경우 점 기호를 기준으로 객체를 표현한다.
* 배열인 경우에는 `[*]` 기호를 이용하여 표기한다.
* A type that extracts all keys of a nested object. If the object contains nested properties,
* the keys are represented using dot notation. For arrays, the keys are represented using
* the `[*]` symbol.
*
* ```ts
* type Example1 = DeepStrictObjectKeys<{ a: { b: 1; c: 2 } }>; // "a" | "a.b" | "a.c"
Expand Down
17 changes: 12 additions & 5 deletions src/types/DeepStrictOmit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,20 @@ type _DeepStrictOmit<T extends object, K extends DeepStrictObjectKeys<T>> =
: ____DeepStrictOmit<T, K>;

/**
* @title 인터페이스에서 특정 키를 제거하는 타입.
* {@link DeepStrictObjectKeys} 을 이용해서 제거할 키를 고를 수 있다.
* @title Type for Removing Specific Keys from an Interface.
*
* The `DeepStrictOmit<T, K>` type creates a new type by excluding properties
* corresponding to the key `K` from the object `T`, while preserving the nested structure.
* It enables precise omission of keys even in deeply nested objects or arrays.
*
* {@link DeepStrictObjectKeys} can be used to determine valid keys for omission,
* including nested keys represented with dot notation (`.`) and array indices represented with `[*]`.
*
* Example Usage:
* ```ts
* type Example1 = DeepStrictOmit<{ a: { b: 1; c: 2 } }, "a.b">;
* type Example2 = DeepStrictOmit<{ a: { b: 1; c: { d: number }[] } }, "a.c[*].d">;
* type Example3 = DeepStrictOmit<{ a: 1 }[], "[*].a">;
* type Example1 = DeepStrictOmit<{ a: { b: 1; c: 2 } }, "a.b">; // { a: { c: 2 } }
* type Example2 = DeepStrictOmit<{ a: { b: 1; c: { d: number }[] } }, "a.c[*].d">; // { a: { b: 1; c: {}[] } }
* type Example3 = DeepStrictOmit<{ a: 1 }[], "[*].a">; // {}[]
* ```
*/
export type DeepStrictOmit<T extends object, K extends DeepStrictObjectKeys<DeepStrictUnbrand<T>>> = _DeepStrictOmit<
Expand Down
17 changes: 12 additions & 5 deletions src/types/DeepStrictPick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,20 @@ import type { RemoveAfterDot } from './RemoveAfterDot';
import type { RemoveLastProperty } from './RemoveLastProperty';

/**
* @title 인터페이스에서 특정 키만을 뽑는 타입.
* {@link DeepStrictObjectKeys} 을 이용해서 뽑을 키를 고를 수 있다.
* @title Type for Selecting Specific Keys from an Interface.
*
* The `DeepStrictPick<T, K>` type creates a new type by selecting only the properties
* corresponding to the key `K` from the object `T`, while preserving the nested structure.
* This type allows safely selecting specific keys, even from deeply nested objects or arrays.
*
* {@link DeepStrictObjectKeys} can be used to determine valid keys for selection,
* including nested keys represented with dot notation (`.`) and array indices represented with `[*]`.
*
* Example Usage:
* ```ts
* type Example1 = DeepStrictPick<{ a: { b: 1; c: 2 } }, "a.b">;
* type Example2 = DeepStrictPick<{ a: { b: 1; c: { d: number }[] } }, "a.c[*].d">;
* type Example3 = DeepStrictPick<{ a: 1 }[], "[*].a">;
* type Example1 = DeepStrictPick<{ a: { b: 1; c: 2 } }, "a.b">; // { a: { b: 1 } }
* type Example2 = DeepStrictPick<{ a: { b: 1; c: { d: number }[] } }, "a.c[*].d">; // { a: { c: { d: number }[] } }
* type Example3 = DeepStrictPick<{ a: 1 }[], "[*].a">; // { a: 1 }[]
* ```
*/
export type DeepStrictPick<T extends object, K extends DeepStrictObjectKeys<T>> = DeepStrictOmit<
Expand Down
24 changes: 24 additions & 0 deletions src/types/DeepStrictUnbrand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,30 @@ type Unbrand<T extends Primitive & Record<any, any>> = T extends string & Record
? Extract<undefined, Omit<T, any>>
: T;

/**
* @title Type for Recursively Removing Branding Types.
*
* The `DeepStrictUnbrand<T>` type recursively processes the type `T` to remove any branding
* that may have been added to primitive types or object properties. Branding often occurs when
* extending or augmenting primitive types for type safety, and this type "unbrands" them, restoring
* the original primitive type (e.g., `string`, `number`, `boolean`, etc.).
*
* The helper type `Unbrand<T>` is used to handle primitive types and their respective branding,
* by stripping off any additional properties that may have been added to them.
*
* The recursion goes through:
* - Arrays: It recursively processes elements of the array, maintaining deep unbranding.
* - Objects: It recursively processes each key in the object, unbranding any branded properties.
* - Primitives: It removes branding from primitive types (`string`, `number`, `boolean`, `symbol`, `null`, `undefined`).
* - Dates: The `Date` type is preserved as it is.
*
* Example Usage:
* ```ts
* type Example1 = DeepStrictUnbrand<{ a: string & { __brand: 'unique' } }>; // { a: string }
* type Example2 = DeepStrictUnbrand<{ a: { b: number & { __brand: 'id' } } }>; // { a: { b: number } }
* type Example3 = DeepStrictUnbrand<Array<string & { __brand: 'email' }>>; // Array<string>
* ```
*/
export type DeepStrictUnbrand<T> =
T extends Array<Date>
? Array<Date>
Expand Down
2 changes: 1 addition & 1 deletion src/types/ElementOf.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/**
* @title 배열의 요소 타입을 추론하는 타입.
* @title Type for Inferring the Element Type of an Array.
*/
export type ElementOf<T extends Array<any>> = T extends Array<infer Element> ? Element : never;
8 changes: 6 additions & 2 deletions src/types/Equal.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
/**
* 구현 방법
* Implementation method
*/
type Expression<X> = <T>() => T extends X ? 1 : 2;

/**
* @title 두 타입이 동일한 타입인지 확인하기 위한 타입
* @title Type for Checking if Two Types are Equal.
*
* The `Equal<X, Y>` type uses conditional types and a helper type `Expression<X>`
* to determine if two types `X` and `Y` are the same. It returns `true` if they are
* equal, and `false` otherwise.
*/
export type Equal<X, Y> = Expression<X> extends Expression<Y> ? true : false;
22 changes: 18 additions & 4 deletions src/types/GetMember.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
/**
* @title 어떤 키로부터 멤버만을 조회하는 타입.
* @title Type for Retrieving Members from a Specific Key.
*
* The `GetMember<T, O>` type extracts the part of the key `T` after the given prefix key `O`.
* If `T` starts with `O`, it returns the remaining portion of the key after `O`.
*
* Example Usage:
* ```ts
* type b = GetMember<"a.b", "a">;
* type b_c = GetMember<"a.b.c", "a">;
* type b = GetMember<"a.b", "a">; // "b"
* type b_c = GetMember<"a.b.c", "a">; // "b.c"
* ```
*/
export type GetMember<T extends string, O extends string> = T extends `${O}.${infer Rest}` ? Rest : never;

/**
* @title 어떤 키로부터 요소 멤버의 키를 조회하는 타입.
* @title Type for Retrieving the Key of an Element Member from a Specific Key.
*
* The `GetElementMember<T, First>` type handles both regular keys and array element keys.
* If the key `T` represents an array element (denoted by `[*]`), it returns the key after the array element.
* Otherwise, it falls back to using `GetMember<T, First>` to retrieve the remaining portion of the key.
*
* Example Usage:
* ```ts
* type ElementKey = GetElementMember<"a[*].b", "a">; // "b"
* type NestedKey = GetElementMember<"a.b.c", "a">; // "b.c"
* ```
*/
export type GetElementMember<T extends string, First extends string> = T extends `${First}[*].${infer Rest}`
? Rest
Expand Down
15 changes: 15 additions & 0 deletions src/types/GetStrictObjectLastKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,21 @@ type __DeepStrictObjectKeys<
: never
: never;

/**
* @title Type for Extracting the Last Level Keys from Nested Objects, Including Array Elements.
*
* The `DeepStrictObjectLastKeys<T, Joiner, P>` type extracts the keys from the last level of a nested object `T`,
* with support for arrays. It returns keys with array indices (`[*]`) and object keys using a custom separator defined
* by the `Joiner` object.
* - For arrays, it appends array indices (`[*]`) followed by the key of the element.
* - For objects, it recursively traverses the nested structure and appends the last level keys.
*
* Example Usage:
* ```ts
* type Example1 = DeepStrictObjectLastKeys<{ a: { b: { c: number[] } } }>; // "a.b.c"
* type Example2 = DeepStrictObjectLastKeys<{ a: { b: number[]; c: { d: string }[] } }>; // "a.b" | "a.c" | "a.c[*].d"
* ```
*/
export type DeepStrictObjectLastKeys<
T extends object,
Joiner extends { array: string; object: string } = {
Expand Down
16 changes: 13 additions & 3 deletions src/types/GetType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,22 @@ type ToObject<T> = Allow<T, object>;

/**
* @title The type that pulls out the type of a particular key on an interface.
* @template {T}
* @template {K}
*
* This type extracts the type of a specific key from a nested object,
* supporting arrays and deeply nested keys. It uses `DeepStrictObjectKeys`
* to handle the extraction of keys and correctly resolves the type for the given key.
*
* - If the key points to a primitive value, the type is returned directly.
* - If the key points to an array, the type of the array elements is resolved.
* - It supports nested keys using `.` notation to handle deep objects and arrays.
*
* @template T The interface type.
* @template K The key string, which can represent a nested key path.
*
* Example usage:
* ```ts
* type Example1 = GetType<{ a: { b: { c: number } } }, "a.b">; // { c: number }
* type Example = GetType<{ a: { b: { c: number } } }, "a.b.c">; // number
* type Example2 = GetType<{ a: { b: { c: number } } }, "a.b.c">; // number
* ```
*/
export type GetType<T extends object, K extends DeepStrictObjectKeys<T>> =
Expand Down
12 changes: 11 additions & 1 deletion src/types/IsAny.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
/**
* @title `any` 타입을 검증하는 타입.
* @title Type for checking if a type is `any`.
*
* This type uses a conditional check to determine if the provided type `T` is `any`.
* - It works by checking if the type `T` extends from a condition that results in `true` when `T` is `any`, and `false` otherwise.
* - If `T` is `any`, it resolves to `true`, otherwise it resolves to `false`.
*
* Example usage:
* ```ts
* type Test1 = IsAny<any>; // true
* type Test2 = IsAny<string>; // false
* ```
*/
export type IsAny<T> = 0 extends 1 & T ? true : false;
12 changes: 11 additions & 1 deletion src/types/IsUnion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ type IsPartitionSameEntire<T, P = T> = T extends any // T를 각각의 요소
: never;

/**
* @title 유니온 타입을 검증하는 타입.
* @title Type for checking if a type is a union type.
*
* This type uses the `IsPartitionSameEntire` type to check whether the provided type `T` is a union type.
* - It works by partitioning the type `T` and checking if the type consists of multiple distinct elements.
* - If the type `T` is a union type, the result will be `true`, otherwise `false`.
*
* Example usage:
* ```ts
* type Test1 = IsUnion<string | number>; // true
* type Test2 = IsUnion<string>; // false
* ```
*/
export type IsUnion<T> = Equal<IsPartitionSameEntire<T>, boolean> extends true ? true : false;

0 comments on commit 3cc8c88

Please sign in to comment.