[230624] Typescript 공식문서 & 문제풀기

1. Typescript Indexed Access Types 정독 및 정리 완료

  • 인덱스 접근 타입(indexed acces type) 을 사용하여 특정 속성을 추출할 수 있음
  • 인덱스 접근 타입은 [ ] 대괄호를 사용
  • 위 예시는 Age 는 Person 타입의 age 속성의 타입인 number가 됨
  • 인덱싱 타입은 유니온, keyof 또는 다른 타입들과 함께 사용 가능 → 인덱싱 타입 자체가 타입이기 때문 (속성의 타입을 가져오는 기능을 제공하는 타입)
// @errors: 2538 2749
type Person = { age: number; name: string; alive: boolean };
// ---cut---
const key = "age";
type Age = Person[key];
===> 불가능

type Person = { age: number; name: string; alive: boolean };
// ---cut---
type key = "age";
type Age = Person[key];
===> 가능
  • const (상수)를 사용하여 타입으로 인덱싱할 수 없다.
  • 하지만 type 타입별칭을 사용해서 할 수는 있다.

유니온 예시

type Person = { age: number; name: string; alive: boolean };
// ---cut---
type I1 = Person["age" | "name"];
//  I1 = string | number

type I2 = Person[keyof Person];
//   string | number | boolean

type AliveOrName = "alive" | "name";
type I3 = Person[AliveOrName];
//   boolean | string

존재하지 않는 프로퍼티를 인덱싱하면 오류 발생

typeof 와 결합해서 편리하게 타입 가져오기

const MyArray = [
  { name: "Alice", age: 15 },
  { name: "Bob", age: 23 },
  { name: "Eve", age: 38 },
];

type Person = (typeof MyArray)[number];

// 타입 Person은 { name: string; age: number; }입니다.

type Age = (typeof MyArray)[number]["age"];

// 타입 Age는 number입니다.

2. Conditional Types 정독 및 정리 완료

조건부 타입

  • 조건부 타입은 (condition ? trueExpression : falseExpression) js 조건 표현식과 비슷한 형식을 가짐
  • extends 의 왼쪽에 있는 타입이 오른쪽에 있는 타입에 할당 가능한 경우 첫번째 분기 반환
  • 그렇지 않은 경우 두번째 분기 반환

조건부 타입 제네릭과 함께 응용 방법

// number 이면 IdLabel , 아니면 NameLabel
type NameOrId<T extends number | string> = T extends number
  ? IdLabel
  : NameLabel;

function createLabel<T extends number | string>(idOrName: T): NameOrId<T> {
  throw "unimplemented";
}

let a = createLabel("typescript");
// let a: NameLabel

let b = createLabel(2.8);
// let b: IdLabel

let c = createLabel(Math.random() ? "hello" : 42);
//let c: NameLabel | IdLabel

조건부 타입으로 제한하기

// 위와 같이 message 를 속성으로 사용하고 있냐 없냐 제한을 둘 수 있음
type MessageOf<T> = T extends { message: unknown } ? T["message"] : never;

interface Email {
  message: string;
}

interface Dog {
  bark(): void;
}

type EmailMessageContents = MessageOf<Email>;
//type EmailMessageContents = string

type DogMessageContents = MessageOf<Dog>;
//type DogMessageContents = never

조건부 타입 내에서 추론하기

  • infer 타입 시스템에서 미리 정의된 키워드
  • infer 키워드를 쓰면 조건부 타입에서 제너릭처럼 사용할 수 있음 (타입을 추론함)
  • true 분기에서 사용 가능
  • infer 는 조건부 extends 절에서만 사용이 가능하다
T extends infer U ? X : Y
  • 위에가 기본 구조인데 U가 타입 추론이 가능하면 타입이 X가 들어간다.
type Flatten<Type> = Type extends Array<infer Item> ? Item : Type;

분배적 조건부 타입

  • 조건부 타입이 제네릭 타입을 다룰 때, 유니온 타입으로 주어지면 분배적이 됨
type ToArray<Type> = Type extends any ? Type[] : never;

type StrArrOrNumArr = ToArray<string | number>;
// type StrArrOrNumArr = string[] | number[]
  • 분배적 조건부 타입은 유용할때도 많지만 때로는 예상치 못한 결과를 초례함
type ToArray<Type> = Type extends any ? Type[] : never;

type StrArrOrNumArr = ToArray<string | number>;
// type StrArrOrNumArr = string[] | number[]
  • 위와 같이 넣으면 (string number) [] 가 아니라 string[] number[] 임
type ToArrayNonDist<Type> = [Type] extends [any] ? Type[] : never;

// 'StrArrOrNumArr' is no longer a union.
type StrArrOrNumArr = ToArrayNonDist<string | number>;
//   (string | number) []
  • 방지하려면 양 옆에 괄호를 넣어주면 (string number) [] 타입이 된다.

3. Typescript 3문제 품

Categories:

Updated:

Leave a comment