여기서 덕 타이핑(Duck Typing) 이란 동적 타이핑의 한 종류로, 객체의 변수 및 메소드의 집합이 객체의 타입을 결정하는 것을 말한다.
쉽게말해객체가 어떤 타입에 부합하는 변수와 메서드를 가질 경우 객체를 해당 타입에 속하는것으로 간주하는 방식 오리와 같은 특성을 지닌다면 오리가 아니더라도 오리인것으로 간주한다.
interface Vector {
x: number;
y: number;
}
function normalize(input: Vector) {
return Math.sqrt(input.x * input.x + input.y * input.y)
}
interface Square {
name: string
x: number;
y: number
}
const square: Square = {name: 'sq', x:1, y:1}
normalize(square)
위 코드를 보면 Vector 와 Square 간의 관계를 선언하지 않았지만 타입을 넘겨줄 수 있다.
매개변수의 속성들이 매개변수의 타입에 선언된 속성만 가질거라 생각하기 쉬운대 이러한 타입은 봉인된(sealed) 또는 정확한(precise) 타입이라고 불리며 ts에서는 표현할 수 없다. 좋든 싫든 ts에서는 타입은 열려(open)있다.
아래 코드를 보면 key는 x 또는 y 중 하나이고 값은 number로 생각하기 쉽지만, 타입 오류가 발생한다.
function sum(input: {x:number, y: number}) {
let result = 0;
for(let key in input) {
result += input[key] // No index signature with a parameter of type 'string' was found on type '{ x: number; y: number; }'
}
return result
}
그이유는 input으로 오는 값은 Vector 가 가진 속성을 포함한 다른 객체가 올 수 있기 때문에 ts 오류를 발생 시킨다.
이를 해결하기 위해 루프보다는 모든 속성을 각각 더하는 구현이 더 나을 수 있다.
function sum(input: {x:number, y: number}) {
return input.x + input.y
}
- ts는 구조적 (덕)타이핑 기반
- 구조적 타이핑은 유닛 테스트를 쉽게 작성하게 해준다
- 클래스 역시 구조적 타이핑 규칙을 따른다.
- 클래스의 인스턴스가 예상과 다를 수 있다.
ts의 타입 시스템은 점진적(gradual)이고 선택적(optional)이다. 코드에 타입을 조금씩 추가할 수 있기 때문에 점진적이며 언제든지 타입 체커를 해제할 수 있기 때문에 선택적이다. 이 기능들의 핵심은 any 타입이다.
타입선언을 추가하는데 시간을 쓰고 싶지 않아 any를 쓴다면 타입스크립트의 많은 장점을 누리지 못한다.
let age: number
age = '12' as any // NO ERROR
위 코드처럼 any타입은 타입체크를 무시한다.
function calculate(input: number) {...}
let date: any = '1992'
calculate(date)// NO ERROR
function calculateAge(birthDate: Date): number {
return 0;
}
let birthDate: any = "1995-12-22";
calculateArea(birthDate); // OK 가 안되는 이유는 birthDate는 Date 타입이 아니기 때문이다.
함수를 작성할때 약속된 타입의 인자를 제공받길 원하는데 인자가 any타입이면, 함수인자의 타입을 무시한다.
어떤 심볼에 타입이 있다면 ts 언어 서비스는 자동완성 기능과 적절한 도움말을 제공한다
그러나 any 타입인 심벌을 사용하면 아래 코드처럼 아무런 도움을 받지 못한다.
let person: any = { first: 'Ahn' };
person.first
person. // 자동완성 기능이 동작하지 않는다.
이렇게 ts 언어서비스는 any 타입에 대해 자동완성기능과 리팩토링 기능을 제공하지 못한다.
애플리케이션 상태 같은 객체를 정의하려면 꽤 복잡한데, 상태 객체 안에 있는 수많은 속성의 타입을 일일이 작성해야해서 any 타입을 사용하면 간단히 끝내버릴 수 있다.
그러나 이때 any를 사용하면 안된다. 객체를 정의할 때 특히 문제가 되는데, 상태 객체의 설계를 감춰버리기 때문이다.
그리하여 any 타입을 사용하면 타입설계가 잘 되었는지 알 수가 없다.
타입이 실제값과 일치한다면 타입정보를 기억해 둘 필요가 없기 때문에, 기억해야할 정보의 양을 크게 줄일 수 있지만 수많은 any 타입은 실제 타입을 기억해야하므로 일을 어렵게 만든다.
그래서 기존에 js로 구현되어 있는 웹 서비스 코드에 ts를 점진적으로 적용할 때 활용하면 좋은 타입이다.