타입스크립트 Section 6 : 고급 타입

BRANDY·2023년 3월 5일
0

인터섹션 타입

두 타입을 하나로 결합하는 방법으로 기존 타입을 대체하지 않으면서 새로운 필드를 추가하고 싶을 때 '&'를 사용한다.

type Admin = {
    name: string;
    privileges: string[];
};

type Employee = {
    name: string;
    startDate: Date;
};

type ElevatedEmployee = Admin & Employee;
// 인터섹션 타입

const el: ElevatedEmployee = {
    name: 'Max',
    privileges: ['create-server'],
    startDate: new Date()
}

또한 유니언 타입과

interface Person {
  name: string;
  age: number;
}
interface Developer {
  name: string;
  skill: string;
}
function introduce(someone: Person | Developer) {
  someone.name; // O
  someone.age; // X 타입 오류
  someone.skill; // X 타입 오류
}

유니언 타입 + 인터섹션 타입을 합친 예시가 있는데 유니언 타입은 a타입 or b타입이다.

type Combinable = string | number;
type Numeric = number | boolean;

type Universal = Combinable & Numeric; // number
// number만 겹치기 때문이다.

타입가드에 대한 추가정보

특정 속성이나 메소드를 사용하기 전에 그것이 존재하는지 확인하거나 타입을 사용하기전에 이 타입으로 어떤 작업을 수행할 수 있는지 확인하는 개념 또는 방식

function add(a: Combinable, b: Combinable) {
    if(typeof a === 'string' || typeof b === 'string') {
    // 타입 가드 구문
        return a.toString() + b.toString();
    }
    return a + b;
}

구별된 유니언

타입 가드를 쉽게 구현할 수 있게 해주는 유니언 타입이며 속성을 사용해서 어떤 객체와 작업을 수행하는지 확인할 수 있다.

interface Square {
    kind: "square";
    size: number;
}

interface Rectangle {
    kind: "rectangle";
    width: number;
    height: number;
}
type Shape = Square | Rectangle;

kind라는 멤버 속성이 있는데, 이 속성은 모든 유니온 구성원에 존재하는 리터럴 타입입니다

interface Square {
    kind: "square";
    size: number;
}

interface Rectangle {
    kind: "rectangle";
    width: number;
    height: number;
}
type Shape = Square | Rectangle;

이런 경우, 구별 속성(여기선 kind)에 대해 타입 가드 스타일의 검사 (==, ===, !=, !==) 또는 switch를 사용하면 TypeScript가 특정한 리터럴을 가진 객체를 대상으로 한다는 것을 알아채고 타입 좁히기를 실행해줍니다

function area(s: Shape) {
    if (s.kind === "square") {
        // 이것으로 TypeScript가 `s`가 `Square`임을 알게 됨 ;)
        // 그러므로 `Square`의 멤버를 안전하게 사용할 수 있음 :)
        return s.size * s.size;
    }
    else {
        // `Square`가 아님? 그러면 TypeScript는
        // 이것이 `Rectangle`일 수 밖에 없음을 알게 됨 ;)
        // 그러므로 `Rectangle`의 멤버를 안전하게 사용할 수 있음 :)
        return s.width * s.height;
    }
}

형 변환

타입스크립트가 감지하지 못하는 특정 타입의 값을 알려주며 변환하고자 하는 요소 앞, 타입을 알려주고자 하는 요소 앞에 추가한다.

const userInputElement = <HTMLInputElement>document.getElementById('user-input');
const userInputElement = document.getElementById('user-input')! as HTMLInputElement;

인덱스 속성

인덱스 타입 : 속성이 정해져 있지 않고 동적으로 처리해야 할 경우 사용

interface Props {
    [key: string]: string;
}

함수 오버로드

동일한 함수에 여러 함수의 시그니처를 정의할 수 있으며 자체적으로 반환 타입을 추론하지 못하는 경우 유용하며, 함수에서 지원할 수 있는 다양한 조합에 대해 어떤것이 반환되는지 명확하게 알 수 있다.

function add(a: number): number;
function add(a: number, b: number): number);
function add(a: Combinable, b: Combinable) {
     ...
 }

선택적 체이닝

정의되어 있는지 확실하지 않은 요소에 '?'를 추가하여 정의되어 있지 않더라도 런타임 에러를 발생시키지 않게 한다.

onst fetchedUserData = {
    id: 'u1',
    name: 'Max',
    // job: {title: 'CEO', description: 'My own company'}
{;

console.log(fetchedUserData?, job?.title);
 

Null 병합

null데이터 처리에 도움을 주는 기능으로 어떤 데이터나 입력값이 null인지 undefined인지, 유효한 데이터인지 알 수 없는 경우 이를 다른 상수나 변수로 저장하여 이것이 null이라면 폴백(fallback)값을 저장하도록 할 수 있다.

const userInput = undefined;
coonst storedData = userInput ?? 'DEFAULT';

console.log(storedData); // DEFAULT

a ?? b
// a가 null, undefined, 유효한 데이터가 아니면 a 그 외의 경우는 b
profile
프런트엔드 개발자

0개의 댓글