리팩터리 2판 중 덕타이핑이라는 용어가 등장했다. 해당 용어를 다음과 같이 정의하고 있는데, 명확하게 와닿지 않는다.
요약: 객체의 변수 및 메소드의 집합이 객체의 타입을 결정
그래서 자료를 찾아 위의 내용을 코드로 풀이해 봤다.
interface Quackable {
sound: 'quack';
cry: () => Quackable['sound'];
}
class Duck implements Quackable {
sound: 'quack';
cry() {
return this.sound;
}
}
class Pig {
sound: 'quack';
cry() {
return this.sound;
}
}
function cryQuack(Quackable: Quackable): void {
Quackable.cry();
}
cryQuack(new Duck());
cryQuack(new Pig()); // Qauckable을 상속받지 않은 Pig 클래스도 정상적으로 실행이 된다.
위의 코드를 보면 Qauckable을 상속받지 않은 Pig 클래스가 cryQuack이라는 함수의 인수: Quackable 로 입력되었더라도 실행이 된다. java였다면 class 이름에 의해 오류가 발생했겠지만 ts의 경우는 같은 구조이기 때문에 실행이 된다. 즉 javascript에서는 ojbect가 어떤 타입을 가지고 있는지 그 자체는 중요하지 않다. 같은 형태의 데이터를 가진 구조를 중심으로 파악한다.
덕 타이핑은 동적 타이핑의 한 종류이기 때문에 동일한 장단점을 가지고 있다.
정적 타이핑보다 사용하기 편하고, 코드가 짧아지며 그 만큼 개발 시간을 줄여준다. 보통 정적 타이핑 언어가 인터페이스를 사용하기 때문에 코드가 길어질 수 있으며, 때로 과도한 리팩터링이 필요하게 된다. 타입스크립트도 인터페이스 비슷한 방식으로 타이핑이 가능하다.
그렇다면 타입스크립트도 덕 타이핑으로 타입 비교를 하는 것 같은데 동적 타이핑 언어인가? 답은 X 다. 정확히 말하면 타입스크립트는 structure typing 언어다. 정적 타이핑 언어이면서 동일한 구조임을 컴파일 타임에 확인한다.
출처: https://www.typescriptlang.org/docs/handbook/type-compatibility.html
한 가지 예시를 들면 정적 타이핑의 경우 컴파일 시간에 타입을 계산한다. 따라서 컴파일하는 과정이 느리고, 반면 실행시간에 이득을 가져간다. 반대로, 덕 타이핑은컴파일은 빠르고, 실행시간이 느리다. 가장 큰 단점은 때때로 컴파일 타임에 잠재적인 오류를 발견하지 못한다는 점이다. 사실상 단점이 너무 크기 때문에 product 레벨에서는 권장하지 않는다.
이 단점을 어떻게 극복할 수 있을 까? 위의 특성 때문에 덕타핑과 같은 동적 타이핑을 할 때는 컨벤션(타입을 네이밍에 포함하는 것...), 테스트 드리븐, 문서화를 권장한다.