dev-hamster

[type-challengs] easy 10-14 본문

타입스크립트/type-challenges

[type-challengs] easy 10-14

dev-hamster 2024. 10. 12. 21:19

Includes

JavaScript의 Array.includes 함수를 타입 시스템에서 구현하세요. 타입은 두 인수를 받고, true 또는 false를 반환하자.

U가 T의 구성 요소인지 확인하기 위해 T를 인덱스 접근 타입으로 변경하고 U가 이 유니온 타입에 속하는지 조건부로 true 또는 false를 반환한다. 그런데 이 코드는 primitive type만 통과하고 객체나 타입 자체는 통과하지 않는다. 예를 들어 { a: 'A'}{ }의 서브 타입으로 true를 반환한다.

// 오답
type Includes<T extends readonly unknown[], U> = U extends T[number] ? true : false;

T 배열의 요소를 키로 갖는 타입을 만들고 U가 T의 키인지 확인하면 해결할 수 있을 것 같지만, U가 프로퍼티 키로 사용할 수 있을 때만 통과된다. (참고)

// 오답
type Includes<T extends readonly any[], U> = {
  [P in T[number]]: true
}[U] extends true ? true : false;

이를 해결하기 위해 배열의 첫번째 요소와 타입이 같은지 재귀적으로 타입을 확인해야 한다.

// 정답
type Includes<T extends readonly unknown[], U> =
  T extends [infer First, ...infer Rest]
    ? Equal<First, U> extends true ? true : Includes<Rest, U>
    : false;

infer 키워드를 복습하고 가자. infer은 조건부 타입에서 참으로 평가될 때 사용할 수 있는 타입을 추론하는 데 사용한다.

참고로 @type-challenges/utils 의 Equal은 아래처럼 구현되어 있다.

Equal<X, Y> = 
    (<T>() => T extends X ? 1 : 2) extends 
    (<T>() => T extends Y ? 1 : 2) ? true : false;

Push

Array.push의 제네릭 버전을 구현하자.

T를 배열로 타입을 제한하고 배열 디스트럭쳐링을 이용해 배열 타입을 반환한다.

type Push<T extends unknown[], U> = [...T, U];

Unshift

Array.unshift의 타입 버전을 구현하자.

Push 문제와 동일하다. T와 U 순서만 바꿔주면 된다.

type Unshift<T extends unknown[], U> = [U, ...T];

Parameters

내장 제네릭 Parameters<T>를 이를 사용하지 않고 구현하자.

조건부 타입으로 함수 타입이라면 args를 추론한 D 타입을 반환한다. 하지만 T타입이 함수로 제한하지 않아 함수가 아닌 타입에서 에러가 나지 않아서 아쉽다.

type MyParameters<T> = T extends (...args: infer D) => unknown ? D : any;

const temp = ['1'];
type x = MyParameters<typeof temp>; // 타입 에러가 나지 않는다.

이를 막으려면 T타입을 함수로 제한하면 된다.

type MyParameters<T extends (...args: any[]) => any> = T extends (...any: infer S) => any ? S : any 

'타입스크립트 > type-challenges' 카테고리의 다른 글

[type-challenges] medium 10-13  (0) 2024.10.22
[type-chllenges] medium 05-08  (2) 2024.10.22
[type-challenges] medium 01-04  (0) 2024.10.17
[type-challenges] easy 06-09  (1) 2024.10.11
[type-challenges] easy 01-05  (2) 2024.10.11