📚 책 정보
- 우아한 타입스크립트 with 리액트 (2023)
- 우아한 형제들 웹프론트개발그룹 지음
📝 목차
- 구조적 타이핑
- 구조적 서브 타이핑
📍구조적 타이핑
아래 코드에서는 비슷하면서 서로 다른 타입이 호환된다. 타입스크립트는 구조로 타입을 구분하기 때문. (다른 언어였으면 타입 이름이 다르면 호환 불가)
interface Dog {
age: number;
}
interface Man {
age: number;
}
let sundance = { age: 10 };
let kim = { age: 30 };
sundance = kim; // ok
kim = sundance; // ok
📍구조적 서브타이핑
타입스크립트에서 타입은 집합의 개념이기 때문에, 특정 값이 string or number 타입을 동시에 가질 수 있다
type strOrNum = string | number;
구조적 서브타이핑
- 객체의 프로퍼티를 바탕으로 타입을 구분
- 공통된 프로퍼티가 있으면 호환 가능
아래 코드에서는 Pet 타입이 Cat 타입이 될 수 있지만, 반대는 불가능 (Cat 타입에 있는 age 프로퍼티가 Pet 타입에 없음)
interface Pet {
name: string;
}
interface Cat {
name: string;
age: number;
}
let pet1: Pet;
let cat1: Cat = { name: "jerry", age: 2 };
pet1 = cat1; // ok
// cat1 = pet1; // 에러 -> age가 pet1에 없음
function greet(pet: Pet) {
console.log("hello, " + pet.name);
}
// 매개변수 타입이 달라도 인수가 될 수 있음
greet(cat1); // "hello, jerry"
클래스에 대해서도 동일하게 작동한다. 상속받지 않은 클래스인데도 구조가 비슷하여 호환 가능
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
class Developer {
name: string;
age: number;
sleepTime: number;
constructor(name: string, age: number, sleepTime: number) {
this.name = name;
this.age = age;
this.sleepTime = sleepTime;
}
}
function greet(p: Person) {
console.log(`Hello, I'm ${p.name}`);
}
const developer = new Developer("zig", 20, 7);
// Person 인스턴스 대신 Develop 인스턴스를 사용 가능
greet(developer); // Hello, I'm zig
📍덕 타이핑
- 자바스크립트가 채택한 방식으로, 어떤 타입에 부합하는 프로퍼티나 메서드를 가질 경우, 런타임에 타입 검사를 실행하여 문제가 없으면 같은 타입으로 인식
- 타입스크립트는 자바스크립트의 덕 타이핑을 토대로 구조적 타이핑을 채택하여 타입 안전성과 유연한 타이핑을 동시에 얻고자 함
구조적 타이핑으로 인한 에러
- 아래 코드에서 c 매개 변수에 Cube 타입 보다 많은 프로퍼티를 갖는 객체가 올 수 있어서 에러 발생
interface Cube {
width: number
height: number
depth: number
}
function addLines(c: Cube) {
let total = 0;
for (const axis of Object.keys(c)) {
// c 에 꼭 Cube의 프로퍼티만 갖는 객체가 들어오지 않을 수도 있어서
// c = { width: 1, height: 2, depth: 3, other: 4 } 이여도 Cube 타입에 할당 가능
const length = c[axis];
total += length;
}
}