본문 바로가기
IT/JavaScript & TypeScript

[TypeScript] 타입스크립트의 Duck Typing과 Freshness

by 저당단 2024. 11. 29.

https://blog.naver.com/fontoylab

Duck Typing

타입스크립트의 타입 추론은 값의 형태에 기반하여 이루어지는데, 이걸 구조적 서브타이핑(Structural SubTyping) 또는 덕 타이핑(Duck Typing)이라고 한다.

 

Java 등에서 사용하는 명목적 서브타이핑(Nominal SubTyping)은 명시적으로 타입이나 상속 관계를 지정해주어야 하는 반면, 구조적 서브타이핑은 객체의 프로퍼티를 기반으로 타입을 호환시킨다.

 

// 명목적 서브타이핑 예시

type Animal = {
    name: string;
    age: number;
}

// Duck은 Animal에게 상속받았다고 관계를 명시해두고 있음
type Duck = Animal & {
    isBirdFluInfected: boolean;
}

 

위 코드에서 Duck 타입으로 선언된 객체는 Animal 타입을 파라미터로 가진 함수에 파라미터로 들어갈 수 있다.

 

// 구조적 서브타이핑 예시

type Animal = {
    name: string;
    age: number;
}

type Duck = {
    name: string;
    age: number;
    isBirdFluInfected: boolean;
}

 

구조적 서브타이핑을 지원하는 타입스크립트는 위 코드도 역시 가능하다.

상속 관계가 명시되어 있지 않더라도 Duck은 Animal의 프로퍼티를 모두 포함하고 있기 때문이다.

 

 

Freshness

Freshness라는 개념에 대해 설명해놓은 토스 기술 블로그이다.

 

TypeScript 타입 시스템 뜯어보기: 타입 호환성

타입호환성은 무엇이며 왜 필요할까요? 타입호환이 지원되지 않는 경우가 존재한다는 것을 아셨나요? 평소 익숙했던 개념들에 대해 질문을 던져가며 TypeScript 타입 시스템에 관해 심도있게 알아

toss.tech

요약하면, 모든 객체가 처음 선언될 때는 Fresh Literal로 간주되며, 타입 단언이나 추론을 거치면 Freshness가 사라지고, Fresh한 객체는 구조적 서브타이핑을 지원하지 않는다는 것이다.

 

type Animal = {
    name: string;
    age: number;
}

type Duck = {
    name: string;
    age: number;
    isBirdFluInfected: boolean;
}

// 객체 리터럴이 변수 duck에 할당됨
const duck = {
    name: "QwackCheol",
    age: 5,
    isBirdFluInfected: false
}

const printAnimalInfo = (animal: Animal) => {
    console.log(animal.name, animal.age);
}

// 정상 동작
printAnimalInfo(duck);

 

위 코드는 객체 리터럴이 변수 duck에 할당된 순간 타입 추론이 일어났고, Freshness가 사라졌다.

이 코드라면 구조적 서브타이핑을 지원하므로 정상적으로 타입 호환이 되었다.

 

printAnimalInfo({
    name: "QwackCheol",
    age: 5,
    isBirdFluInfected: false
});

// error TS2353: Object literal may only specify known properties, and 'isBirdFluInfected' does not exist in type 'Animal'.
printAnimalInfo(duck);

 

반면 변수에 할당하지 않고 Fresh한 객체를 그대로 파라미터에 집어넣으니 에러가 발생하였다.

 

어차피 이 함수 파라미터로만 한 번 사용되고 끝나는 객체라, 굳이 이 경우에서까지 구조적 서브타이핑을 지원할 필요가 없기에 이렇게 설계되었다고 한다.

프로퍼티 키에 오타가 생기더라도 잡아주지 못하는 등의 리스크가 타입 유연성에서 오는 이점보다 크기 때문이다.

 

 

 


썸네일은 제가 좋아하는 오리 캐릭터 곽철이입니다.

주제가 Duck Typing이라 넣어봤습니다. 꽉