관리 메뉴

꿈꾸는 개발자

덕 타이핑과 구조적 타이핑 (JS vs TS) 본문

CS지식

덕 타이핑과 구조적 타이핑 (JS vs TS)

rickysin 2023. 6. 16. 19:36

덕 타이핑

런타임에서 사용될 때까지 객체 타입을 검사하지 않는 것을 의미한다. 자바스크립트를 사용해 보았다면 자바스크립트 에러는 런타임에 발생한다는 사실을 알고 있을 것이다. 따라서, 타입스크립트와 다르게 자유도가 높으며 엄격한 타입 체킹 또한 없다. 

 

간단한 코드 예시를 살펴보자

class Duck {
  quack() {
    console.log('꽥!')
  }
  feathers() {
    console.log('깃털은 검정색과 흰색')
  }
}
class Human {
  quack() {
    console.log('사람인데요? 꽥!')
  }
  feathers() {
    console.log('사람이라 깃털은 없어요. 하지만 털은 있습니다.')
  }
}
function inTheForest(duck) {
  duck.quack()
  duck.feathers()
}
inTheForest(new Duck())
inTheForest(new Human())

위 코드를 살펴보면 Human과 Duck 둘 다 메소드로 quack과 feature를 선언했고 동일하게 inTheForest 함수에 넣게 되면 콘솔 로그를 실행하게 된다. 여기에서 주의할 점은 위에서 언급한 대로 quack()를 넣든 feathers()를 넣든 정적 타입과 다르게 런타임에서 판별한다는 것이다.

 

위와 같은 경우에선 에러가 발생하지 않겠지만, 기억해야 할 것은 덕 타이핑이기 때문에 객체뿐만 아니라, 변수 등 아무거나 들어갈 수 있게 된다. 그렇게 되면 quack, feathers와 같은 메서드를 가지고 있지 않기 때문에 런타임 에러가 발생하게 된다. 

 

덕 타이핑의 한계/단점

  • 런타임에서 에러를 뱉어 내기 때문에 함수의 의도와 맞지 않는 코드를 작성할 가능성이 존재한다. 
  • 간단한 코딩이면 상관이 없지만, 대량의 코딩을 작성했을 경우 틈틈이 디버깅을 하지 않는 이상 에러를 찾기 어려울 수 있다. 

덕 타이핑의 장점

  • 빠르게 개발이 가능하다 
  • 자유도가 높은 만큼 생산성이 높다. ( 하나의 함수로 여러 객체에서 사용할 수 있는 함수를 별 다른 어려움 없이 만들 수 있다)  => 정적 타입의 경우 Generic 등을 이용해서 처리해야 하기 떄문에 복잡성이 더 높다.

구조적 타이핑 (타입 호환)

정적 시스템이 타입을 검사하는 경우를 말한다. 구조적 타이핑은 명목적 타이핑과 대조적으로 코드 구조 관점에서 타입이 서로 호환되는지 여부를 판단하는 것이다. 

interface Ironman {
  name: string;
}

class Avengers {
  name: string;
}

let i: Ironman;
i = new Avengers(); // OK, because of structural typing

 

JAVA였다면 위 코드는 에러가 발생했을 것이다. 하지만, 타이스크립트에선 위와 같이 코드를 작성했을 때 정장적으로 작동되는 이유는 자바스크립트와 연관돼 있다. 자바스크립트에선 명시적으로 타입을 지정하기 보단 코드의 구조 관점에서 타입을 지정한다. 간단한게 말해서 객체 "y"r가 최소한 객체 "x"와 동일한 멤버를 가지고 있을 경우 호환이 된다는 의미이다.

interface Vector2D {
  x: number
  y: number
}
interface NamedVector {
  name: string
  x: number
  y: number
}
function calculateLength(v: Vector2D) {
  return Math.sqrt(v.x * v.x + v.y * v.y)
}
const v: NamedVector = { x: 3, y: 4, name: 'mgh' }
calculateLength(v)

위 정의를 기반으로 코드를 봤을 때 "Vector2D의 속성에 해당하는 값이 값을 넣는 타입에 속성으로 존재하는가"를 판단한다고 생각하면 된다. 따라서, 위의 경우 엄밀하게 같은 타입이 아님에도 불구하고 타입 호환이 가능하기 때문에 (구조적 서브 타이핑이라고 함) NameVector를 타입으로 지정하고 객체값을 할당해도 문제가 발생하지 않는 것이다. 

 

집합의 관계라고 생각하면 조금 더 편하게 이해할 수 있을 것 같다.

 

구조적 타이핑의 단점

  • 의도하지 않았지만, 동일한 타입을 가지는 경우 동일한 유형으로 간주될 수도 있다. (명목적 타이핑이 아니기 떄문에)

구조적 타이핑의 장점

  • 덕 타이핑보단 코드의 안정성이 보장된다. 

출처

https://joshua1988.github.io/ts/guide/type-compatibility.html#%ED%83%80%EC%9E%85-%ED%98%B8%ED%99%98-type-compatibility-%EC%9D%B4%EB%9E%80

 

타입 호환 | 타입스크립트 핸드북

타입 호환(Type Compatibility)이란? 타입 호환이란 타입스크립트 코드에서 특정 타입이 다른 타입에 잘 맞는지를 의미합니다. 예를 들면 아래와 같은 코드를 의미합니다. C#이나 Java였다면 위 코드에

joshua1988.github.io

https://vallista.kr/%EB%8D%95-%ED%83%80%EC%9D%B4%ED%95%91%EA%B3%BC-%EA%B5%AC%EC%A1%B0%EC%A0%81-%ED%83%80%EC%9D%B4%ED%95%91/

 

덕 타이핑과 구조적 타이핑

Vallista의 블로그

vallista.kr

https://soopdop.github.io/2020/12/09/duck-typing/

 

TypeScript와 Duck Typing의 관계 쉽게 설명하기

TypeScript와 Duck Typing의 관계 쉽게 설명하기

soopdop.github.io