Skip to content

Commit

Permalink
feat(types): DistributiveOmit 타입 추가 (#647)
Browse files Browse the repository at this point in the history
  • Loading branch information
ssi02014 authored Dec 28, 2024
1 parent 1aa0e45 commit ac6da6e
Show file tree
Hide file tree
Showing 11 changed files with 96 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/young-garlics-smile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modern-kit/types': minor
---

feat(types): DistributiveOmit 타입 추가 - @ssi02014
1 change: 0 additions & 1 deletion packages/types/src/ArrayWithReadonly/index.ts

This file was deleted.

16 changes: 16 additions & 0 deletions packages/types/src/DistributiveOmit/DistributiveOmit.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { describe, it, expectTypeOf } from 'vitest';
import { DistributiveOmit } from '.';

describe('DistributiveOmit', () => {
it('유니온 타입에서 각각의 타입에 대해 Omit을 적용한 타입을 반환해야 합니다. ', () => {
const obj = { a: 1, b: 2 } as
| { a: number; b: number }
| { a: string; c: number };

const result: DistributiveOmit<typeof obj, 'a'> = { b: 2 };

expectTypeOf(result as { b: number } | { c: number }).toEqualTypeOf<
{ b: number } | { c: number }
>();
});
});
20 changes: 20 additions & 0 deletions packages/types/src/DistributiveOmit/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* @description 유니온 타입에서 각각의 타입에 대해 `Omit`을 적용하는 타입입니다.
*
* `조건부 타입`을 사용하여 `분배 법칙`처럼 동작합니다.
*
* @template T - 분배 대상이 되는 유니온 타입
* @template K - 제거할 프로퍼티 키
*
* @example
* type Union = { a: string } | { b: number }
* type Result = DistributiveOmit<Union, 'a'>
*
* // 동작 원리와 순서
* // 1. Result = DistributiveOmit<Union, 'a'>
* // 2. Result = Omit<{ a: string }, 'a'> | Omit<{ b: number }, 'a'>
* // 3. Result = {} | { b: number }
*/
export type DistributiveOmit<T, K extends PropertyKey> = T extends any
? Omit<T, K>
: never;
9 changes: 9 additions & 0 deletions packages/types/src/ExtractMapType/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
/**
* @description Map의 타입에서 키와 값의 타입을 추출하여 튜플로 반환하는 타입입니다.
*
* @template T - 타입을 추출할 Map 타입
* @returns 입력된 타입이 Map인 경우 [키 타입, 값 타입] 형태의 튜플을 반환하고, Map이 아닌 경우 never를 반환합니다.
* @example
* type StringNumberMap = Map<string, number>;
* type Extracted = ExtractMapType<StringNumberMap>; // [string, number]
*/
export type ExtractMapType<T> = T extends Map<infer K, infer V>
? [K, V]
: never;
2 changes: 1 addition & 1 deletion packages/types/src/ExtractSetType/ExtractSetType.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { describe, it, expectTypeOf } from 'vitest';
import { ExtractSetType } from '.';

describe('ExtractSetType', () => {
it('should infer the generic type of a Set', () => {
it('Set의 제네릭 타입을 추론해야 합니다.', () => {
const arr = [1, 2, 3, 4, 5] as const;
const testSet = new Set(arr);
const convertedTestArr = [...testSet];
Expand Down
14 changes: 14 additions & 0 deletions packages/types/src/ExtractSetType/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,15 @@
/**
* @description Set 타입에서 내부 요소의 타입을 추출하는 타입입니다.
*
* @template T - 타입을 추출할 Set 타입
* @returns Set의 내부 요소 타입을 반환합니다. Set이 아닌 경우 never를 반환합니다.
*
* @example
* ```typescript
* type StringSet = Set<string>;
* type Result = ExtractSetType<StringSet>; // string
*
* type NotASet = ExtractSetType<number>; // never
* ```
*/
export type ExtractSetType<T> = T extends Set<infer U> ? U : never;
4 changes: 2 additions & 2 deletions packages/types/src/NegativeNumber/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
* @returns 입력된 타입 T가 음수인 경우 T를 반환하고, 그렇지 않으면 never를 반환
*
* @example
* type validNegativeNumber = NegativeNumber<-1>; // -1
* type invalidNegativeNumber = NegativeNumber<1>; // never
* type ValidNegativeNumber = NegativeNumber<-1>; // -1
* type InvalidNegativeNumber = NegativeNumber<1>; // never
*/
export type NegativeNumber<T extends number> = `${T}` extends `-${number}`
? T
Expand Down
15 changes: 15 additions & 0 deletions packages/types/src/ReadonlyArray/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* @description 읽기 전용 배열을 나타내는 타입입니다.
* 기본 배열 타입은 더 좁은 타입의 읽기 전용 배열과 호환됩니다.
*
* @template T - 배열의 요소 타입
* @returns 읽기 전용 배열 타입
* @example
* ```typescript
* type MyArray = ReadonlyArray<number>;
*
* const myArray: MyArray = [1, 2, 3]; // 허용
* const myArray2: MyArray = [1, 2, 3] as const; // 허용
* ```
*/
export type ReadonlyArray<T> = readonly T[];
12 changes: 12 additions & 0 deletions packages/types/src/WholeNumber/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
import { Integer } from 'Integer';

/**
* @description 양의 정수에 0을 포함한 숫자를 나타내는 타입입니다.
*
* @template T - 숫자 타입 매개변수
* @returns {T} 입력된 숫자가 자연수(0 포함)인 경우 해당 타입을 반환하고, 그렇지 않으면 `never`를 반환합니다.
*
* @example
* type ValidWholeNumber1 = WholeNumber<1>; // 1
* type ValidWholeNumber2 = WholeNumber<0>; // 0
* type InvalidWholeNumber1 = WholeNumber<-1>; // never (음수이므로)
* type InvalidWholeNumber2 = WholeNumber<1.5>; // never (소수이므로)
*/
export type WholeNumber<T extends number> = Integer<T> extends never
? never
: `${T}` extends `-${string}`
Expand Down
3 changes: 2 additions & 1 deletion packages/types/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export * from './Arrayable';
export * from './ArrayWithReadonly';
export * from './DistributiveOmit';
export * from './ExcludeNullish';
export * from './ExtractMapType';
export * from './ExtractNestedArrayType';
Expand All @@ -16,5 +16,6 @@ export * from './ObjectEntries';
export * from './ObjectKeys';
export * from './Primitive';
export * from './Promiseable';
export * from './ReadonlyArray';
export * from './Reference';
export * from './WholeNumber';

0 comments on commit ac6da6e

Please sign in to comment.