interface Animal {
eat: () => void
sleep: () => void
}
class Dog implements Animal {
eat() {}
sleep() {}
}
class Cat implements Animal {
eat() {}
sleep() {}
}
위 코드에서
Dog
에run
이라는 메서드를 추가하고 싶어서 Animal에 run을 추가하게 되면Çat
까지run
메서드를 구현해야 한다.interface를 구현하는 클래스는 메서드 구현의 의무가 있기 때문이다.
이처럼 기존 타입, 인터페이스를 변경하면 이미 그 타입을 사용하고 있는 코드에 똑같은 변경을 해줘야 한다.
만약 해당 타입을 쓰는 모든 코드에 변경을 하지 않고, 특정 코드만 자유롭게 타입 확장을 하고 싶을 땐 어떻게 해야할까?
➡️ Union type
과 Intersection
을 사용하면 된다.
→ |
사용
Or → A타입 혹은 B타입
let one: string | number;
one = '1';
one = 1;
→ 여러 타입 중 하나가 올 것이라고 가정할 때 사용.
type Maybe<T> = T | undefined;
function getStr(str: string): Maybe<string> {
if(str === ''){
return undefined;
}
return str;
}
→ 교차타입으로 &
사용
And → A타입이면서 B타입
const Human = {
think: () => void;
}
const Developer = {
work: () => void;
}
const res: Human & Developer = {
think() {
console.log(`I'm thinking`);
},
work() {
console.log(`I'm working`);
},
};
→ 기존 타입을 대체하지 않으면서 기존 타입에 새로운 필드를 추가하고 싶을 때 사용.
→ 기존의 Human & Developer 타입에 Student 타입을 추가하여 기존 타입은 변경하지 않고 확장할 수 있다.
→ OK
→ Error
Developer와 Designer 타입을 같이 사용할 경우, number & string
타입이 된다.
숫자이면서 문자인 값은 없기 때문에 에러가 발생하게 된다.
→ Ok or Error
Developer와 Designer 타입을 같이 사용할 경우, (number | string) & number
타입이 된다.
number
타입이면서 number
타입인 값은 에러가 발생하지 않는다.number
타입이면서 string
타입은 에러가 발생하게 된다.