typescript duck typing

김지원·2023년 5월 11일

typescript

목록 보기
2/3
post-thumbnail

작성하게 된 이유

typescript 내용을 찾다가 공식 docs 처음에 duck typing에 관련된 내용이 있어 찾아보고 알게 된 사실에 대해 정리해보고자 한다.
(https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html#structural-type-system)

  • docs에 적혀있는 구조적 타입 시스템에 대한 설명

One of TypeScript’s core principles is that type checking focuses on the shape that values have.
This is sometimes called “duck typing” or “structural typing”.
In a structural type system, if two objects have the same shape, they are considered to be of the same type.

번역 해보면

타입스크립트의 핵심 원칙 중 하나는 타입 검사가 값의 모양에 초점을 맞춘다는 것입니다.
이를 "덕 타이핑" 또는 "구조적 타이핑"이라고 부르기도 합니다.
구조적 타입 시스템에서는 두 객체의 모양이 같으면 같은 타입으로 간주합니다.

구조적 타입 시스템에서 두 객체의 모양이 같으면 같은 타입으로 간주한다고 설명하고 있다.

바로 코드로 확인해보자

interface Duck {
    talk(): void;
    name: string;   
}

class IDuck implements Duck {
    name = 'duck';
    talk = () => console.log(`${this.name} 입니다`);
}

class Dog {
    name = 'dog';
    talk = () => console.log(`${this.name} 입니다`);
}

cl

const duck = new IDuck(); 
let dog = new Dog();

function introduce(duck: Duck): void {
    duck.talk();
}

introduce(duck); // duck 입니다
introduce(dog); // dog 입니다 --- 1

dog = duck; 

introduce(dog); // duck 입니다  --- 2

코드를 보면 Duck이라는 인터페이스를 만들어
IDuck은 상속을 받았고 Dog은 구조만 똑같이 한 것을 볼 수 있다.

그리고 introduce 함수에서는 duck이라는 파라미터의 타입을 가장 위에서 선언한 인터페이스 Duck으로 타입을 지정해주었다.

그렇다면 인터페이스를 상속받지 못한 Dog를 생성자로 사용한 dog은 에러가 날까?
그렇지 않다. 구조자체는 IDuck과 Dog가 똑같기 때문이다.

심지어 2번을 보면 타입 Dog으로 만들어진 객체인 dog 변수는 IDuck을 할당하여 결과값을 바꿀 수도 있다.
자바 기준으로는 불가능하지만 타입스크립트는 가능하다.

이유는 구조가 같다면 같은 타입으로 간주하는 duck typing 방식을 사용하기 때문이다.

자바나 C#같은 이름을 기준으로 타입을 나누는 방식(Nominal Typing)을 따른다면 에러가 날 것이다.
하지만 위에서 말했듯이 타입스크립트는 구조가 같다면 같은 타입(Structural Typing)으로 간주하기 때문에 위 코드는 에러가 나지 않는다.
그 것이 오리인지 100% 확실하지는 않다. 하지만 오리처럼 생겼고, 오리처럼 걷고, 오리처럼 헤엄치며, 오리처럼 꽥꽥 소리를 낸다. 이 정도의 추론 단서라면 내가 보는 것이 오리라고 판단해도 전혀 무리는 없을 것이다. - duck test

타입 스크립트는 정적 타이핑을 지원한다며?

위에 동적으로 타입을 지정해줄 수 있는 duck typing만 보면 타입스크립트는 정적인 타이핑을 지원하는게 맞는건가 생각이 들었다.

사실 타입 검사의 기준은 타입을 결정하는 시점이 컴파일 시점런타임 시점인지에 따라 구별된다.

  • Java처럼 컴파일 시점에서 결정된다면 정적 타이핑
  • 파이썬처럼 런타임 시점에서 결정하면 동적 타이핑

타입 스크립트는 컴파일 시점에서 타입이 결정되기 때문에 정적 타이핑을 지원한다는 것이 된다.

let num: number = 1;
num = 'number'; // type error

간단한 예시만 봐도 알 수 있다.

그럼 하는 김에 엄격한 Nominal Typing을 채택하면 되는데 왜 덕 타이핑을 채택했을까..?

생각해보았는데 좀 더 유연하게 타입을 명시해주기 위해 duck typing을 사용하고 있는 것으로 생각된다.
(자바스크립트로 컴파일하기 좋기 위해 사용하는 것 같기도 하다. 물론 개인적인 생각 ㅎㅎ)

참고

profile
backend-developer

0개의 댓글