dev-hamster

[type-chllenges] medium 05-08 본문

타입스크립트/type-challenges

[type-chllenges] medium 05-08

dev-hamster 2024. 10. 22. 18:25

문제 풀기에 앞서…

문제 풀기에 앞서 아직 헷갈리는 내용을 짚고 넘어가보자.

 

정적 타입 검사:

타입스크립트는 프로그램을 실행시키지 않고 오류를 검출한다.

 

점진적 타입 시스템:

타입스크립트는 타입 검사를 점진적으로 적용해 동적 타입처럼 자유롭게 타입을 작성할 수 있다.

let a = 10;  // 타입스크립트가 자동으로 number로 추론 (자동 타입 추론)
let b;       // 타입 명시가 없으므로 b는 암시적으로 any 타입을 가짐
b = "hello"; // b에 어떤 값이든 할당 가능 (any 타입)
b = 42;      // any 타입이기 때문에 타입 오류 없음

 

구조적 타입 시스템이란:

타입스크립트 컴파일러는 두 타입의 명시적 선언이 아닌 프로퍼티를 비교하여 타입을 비교한다. 그러니까 타입 HamsterAnimal이 있을 때, HamsterAnimal를 만족한다. Hamster의 프로퍼티는 Animal를 만족시키기 때문에 Hamster타입에 Animal을 할당할 수 있고 HamsterAnimal타입과 호환이 가능하다.

 

Indexed Access Type:

인덱스를 사용해 객체의 프로퍼티 타입을 추출할 수 있다. 배열 요소의 타입을 가져오려면 Foo[number] 로 하면 된다.

 

infer:

조건부 타입의 extends 절 안에서 infer을 이용해 타입 변수를 추론할 수 있다. 이렇게 추론된 타입은 분기에서 참조될 수 있다.

Tuple to Union

튜플 값으로 유니온 타입을 생성하는 제네릭 TupleToUnion<T>를 구현하세요.

 

배열의 인덱스를 number로 접근해서 타입을 가져오면 된다.

type TupleToUnion<T extends unknown[]> = T[number];

Chainable Options

체인 가능 옵션은 일반적으로 Javascript에서 사용됩니다. 하지만 TypeScript로 전환하면 제대로 구현할 수 있나요?

이 챌린지에서는 option(key, value)get() 두가지 함수를 제공하는 객체(또는 클래스) 타입을 구현해야 합니다. 현재 타입을 option으로 지정된 키와 값으로 확장할 수 있고 get으로 최종 결과를 가져올 수 있어야 합니다.

 

너무 어려워서 정답을 봤다. R 타입은 option 메서드로 점진적으로 타입이 확장된다.

type Chainable<T = object> = {
  option<K extends PropertyKey, V>(
    key: K extends keyof T
         ? (V extends T[K] ? never : K)
         : K,
    value: V
  ): Chainable<Omit<T, K> & Record<K, V>>; // Omit K from T
  get(): T;
}

declare

문제에서 a를 declare로 선언했는데, declare에 대해 알아보자.

declare const a: Chainable 

declare는 타입이나 값을 설명하기 위해 사용할 수 있다. 변수, 객체, 함수 또는 외부 모듈 등에서 타입 정보를 제공하는 용도로 사용할 수 있다. declare 키워드로 선언된 변수는 javascript로 컴파일되지 않는다.

Last of Array

배열 T를 사용하고 마지막 요소를 반환하는 제네릭 Last<T>를 구현합니다.

 

T[length - 1] 식으로 접근하고 싶은데, 타입스크립트는 런타입 값을 알 수 없기 때문에 계산이 안된다.

정답 코드에서는 새로운 배열을 만들고, 이 배열의 T['length'] 를 접근한다.

type Last<T extends unknown[]> = [unknown, ...T][T["length"]]

Pop

배열 T를 사용해 마지막 요소를 제외한 배열을 반환하는 제네릭 Pop<T>를 구현합니다.

 

infer로 추론하고 P를 반환하면 된다.

type Pop<T extends unknown[]> = T extends [...infer P, unknown] ? P : []; 

Shift, Push, Unshift 구현하기

type Shift<T extends unknown[]> = T extends [unknown, ...infer P] ? P : [];

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

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

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

[type-challenges] medium 14-16  (0) 2024.10.25
[type-challenges] medium 10-13  (0) 2024.10.22
[type-challenges] medium 01-04  (0) 2024.10.17
[type-challengs] easy 10-14  (0) 2024.10.12
[type-challenges] easy 06-09  (1) 2024.10.11