타입을 좁히는 방법, 확장하는 방법

beomjin_97·2023년 1월 3일
0

typescript

목록 보기
6/7

1.1 Union Type

  • 여러 타입 중 하나가 올 것이라 가정할 때 사용한다.
let one : string | number
one = 1;
one = 'abc';
  • 동시에 여러 타입이 될 수 없다.
type Human = {
  think: () => void;
};

type Human = {
  think: () => void;
};

type Dog = {
  bark: () => void;
};

declare function getType(): Human | Dog;

const creature = getType() 
creature.think(); // Property 'think' does not exist on type 'Human | Dog'. 
                  // Property 'think' does not exist on type 'Dog'.
                  
creature.bark();  // Property 'bark' does not exist on type 'Human | Dog'. 
                 // Property 'bark' does not exist on type 'Human'.

1.2 Intersection Type

  • A타입 이면서 B타입이라는 의미
  • &로 묶인 모든 타입을 만족해야 한다.
  • 기존 타입을 수정하지 않으면서 기존 타입에 새로운 필드를 추가(확장)하고 싶을 때 사용한다.
type Human = {
  think: () => void;
};

type Developer = {
  work: () => void;
};

const me: Human & Developer = {
  think() {},
  work() {},
};
  • 타입간에 겹치는 필드가 있는 경우 에러가 발생할 수 있다.
type A = {
  output: string;
  test: string | number
};
type B = {
  output: number;
  test: string
};

const obj: A & B = {
  output, // Type 'any' is not assignable to type 'never'.
  test  // only 'string' Type is assignable. 
};

2. Type Guard

데이터의 타입을 알 수 없거나, 될 수 있는 타입이 여러개라고 가정할 때, 구별할 수 있는 단서들을 활용하여 조건문을 통해 데이터의 타입을 좁혀나가는 것.
에러를 최소화하는 방어적인 코드 작성 가능.

type Human = {
  think: () => void;
};

type Dog = {
  tail: string;
  bark: () => void;
};

declare function getType(): Human | Dog;

const creature = getType();
if ("tail" in creature) {
  creature.bark();
} else {
  creature.think();
}
  • 구별 단서 : instanceof 활용, typeof 활용, in 활용, literal type을 활용

3. Optional Chaining

  • obj?.propery
  • 접근하는 객체가 null 또는 undefined이면 undefined를 리턴. 그렇지 않은 경우는 데이터 값을 리턴한다.
  • && 는 falsy한 값(alse, null, undefined, ‘’, 0, -0, NaN) 모두를 체킹한다.
  • array와 함수에도 사용할 수 있다.
    ex) comments?.[0] add?.()

4. Nullish Coalescing Operator

  • null 병합 연산자 A ?? B
  • 좌항이 null, undefined인 경우에만 B를 반환
  • A || B 에서는 A가 falsy값인 경우 바로 B를 반환하는 것에 반해, A ?? B는 A가 undefined, null이 아니라면 falsy 값이라해도 A를 반환한다.

5. Functional Overloading

  • 파라미터의 형태가 다양한 여러 케이스에 대응하는 같은 이름을 가진 함수를 만드는 것이다.
  • 함수의 다형성을 지원한다.
  • 제네릭과 달리 타입을 선언하는 시점에 타입이 추론된다.

선언시 주의할 점

  • 함수의 이름이 같아야 한다.
  • 매개변수의 순서가 같아야 한다.
  • 반환타입이 같아야 한다.
  • 타입 선언부는 런타임에서 제거된다.
class User {
  constructor(private id: string) {}

  setId(id: string): string;  // 런타임에 제거됨
  setId(id: number, radix: number): string; // 런타임에 제거됨

  setId(id: string | number, radix?: number): string {
    return id.toString(radix);
  }
}

6. type Assertion

  • 타입스크립트가 추론하지 못하는 타입을 as로 명시해주는 것
  • 타입 선언과 달리 개발자에 의존하는 타입 (실수할 수 있는 여지가 충분히 존재)
  • 실제 데이터 타입을 변경하지 않고 타입 에러가 나지 않게끔만 한다.
let someValue:unknown = 'this is a string'

let strLength: number = (someValue as string).length

7. Index Signature

  • 인덱스 시그니처에 대해서도 타입을 지정할 수 있다.
  • 객체의 프로퍼티를 정확히 알 수 없을 때 사용한다.
  • 너무 많은 프로퍼티를 다 선언할 수 없을 때 사용한다.
type ArrStr = {
  [key1: string]: string;
  [key2: number]: string;
};

type ArrStrs = Record<string|number, string>
profile
Rather be dead than cool.

0개의 댓글