1. 인터섹션 타입(Intersection Type)
이 타입은 다른 타입과 합칠 수 있도록 도와주는 문법이다.(interface도 된다)
쓰는 방법은 어렵지 않다.
아래 intersection type이 적용된 ElevatedEmployee의 내용으로는
Admin과 Employee 타입이 합친 상태일 것이다.
ElevatedEmployee의 타입 내용
name: string;
privileges: string[];
startDate: Date
//typescript
type Admin = {
name: string;
privileges: string[];
};
type Employee = {
name: string;
startDate: Date;
};
// intersection type
type ElevatedEmployee = Admin & Employee;
const el: ElevatedEmployee = {
name: "Gunbro",
privileges: ["create-server"],
startDate: new Date(),
};
난 여기서 궁금한 점이 생겼다.
만약, 같은 이름은 있는데 타입이 다르다면 어떻게 될까?
alias type인 admin의 name을 number로 바꾸었더니
el의 속성인 name이 오류가 생겼다.
내용은 아래와 같은 내용이었다.
string' 형식은 'never' 형식에 할당할 수 없습니다.ts(2322)
app.ts(2, 3):
필요한 형식은 여기에서 'ElevatedEmployee' 형식에 선언된 'name' 속성에서 가져옵니다.
만약 두 개의 타입에서 같은 속성인데 타입이 다르다면,
오류가 나오니 주의하자!
type Admin = {
name: string;
privileges: string[];
};
type Employee = {
name: number;
startDate: Date;
};
// intersection type
type ElevatedEmployee = Admin & Employee;
//name에 오류 발생!!
const el: ElevatedEmployee = {
name: "Gunbro",
privileges: ["create-server"],
startDate: new Date(),
};
2. 타입 가드(Type Guard)
타입 가드는 용어 그대로 해석하면 된다.
타입 가드는 말로만 들으면 "어디서 사용할까?"라고 생각할 수 있다.
생각보다 많이 사용된다.
주로
어떤 함수의 매개변수가 유니온 타입과 같이 단일 타입이 아닌 경우에 타입가드가 사용된다.
왜 사용되어야 하냐면 해당 타입은 단일 타입이 아니어서 없는 속성을 쓸 수가 있게된다.
이러한 오류를 방지하기 위해 타입가드의 조건으로 instaceof, in, typeof 많이 쓰인다.
아래의 코드에서 타입가드는 대상이 Object일 때와 Class일 때로 나누어서 작성되어 있다.
//typescript
type Bird = {
name: string;
habitat: string;
};
type Dog = {
name: string;
age: number;
};
type TwoKindAnimals = Bird | Dog;
function printText(animal: TwoKindAnimals) {
//타입 가드
if ("age" in animal) {
console.log("이 동물의 나이는" + animal.age);
//타입 가드
} else if ("habitat" in animal) {
console.log("이 동물의 서식지는" + animal.habitat);
}
}
const pomerian = {
name: "포포",
age: 5,
};
//포메리안이 들어갔는데 포메리안에는 habitat이 없다.
//타입가드가 없었다면 오류가 발생했을 수 있다.
printText(pomerian);
class Truck {
drive() {
console.log("트럭으로 운전 중!");
}
}
class Bus {
constructor(public count: number) {
this.count = count;
}
drive() {
console.log("버스로 운전 중!");
}
countPeople() {
console.log(this.count + "명 버스에 타고 있어요");
}
}
const truck = new Truck();
const bus = new Bus(10);
type Car = Truck | Bus;
function printCar(c: Car) {
//타입 가드
if (c instanceof Truck) {
console.log("현재는 트럭입니다.");
c.drive();
}
//타입 가드
if (c instanceof Bus) {
console.log("현재는 버스입니다.");
c.drive();
c.countPeople();
}
/* 아래처럼 써도 된다.
if ("countPeople" in c) {
console.log("현재는 버스입니다.");
c.drive();
c.countPeople();
}
*/
}
printCar(bus);
결과사진
3. 구별 유니온(Discriminated Union)
구별 유니온은 타입가드에서 썼던 in 키워드에서 나올 수 있는 오류를
줄여 준다.
만약에 아래의 코드처럼 사용한다면 오류가 난다.
(아래의 코드는 위의 코드와 이어진다.)
//typescript
function printCar(c: Car) {
//타입 가드
if (c instanceof Truck) {
console.log("현재는 트럭입니다.");
c.drive();
}
//타입 가드
if (c instanceof Bus) {
console.log("현재는 버스입니다.");
c.drive();
c.countPeople();
}
// 오류!
if ("counPeople" in c) {
console.log("현재는 버스입니다.");
c.drive();
c.countPeople();
}
}
c라는 객체에 countPeople 함수가 있지만,
오타로 인하여 counPeople로 입력했다.
in 키워드를 사용하면 해당 객체의 속성을 찾는데,
우리가 원하는 결과가 안나오고 오류가 나온다.
이러한 실수를 줄이기 위해서 구별 유니온을 사용한다.
용어는 어렵지만 스위치문을 뜻한다.
//typescript
interface Bird {
type: "bird";
flyingSpeed: number;
}
interface Hourse {
type: "hourse";
runningSpeed: number;
}
type Animal = Bird | Hourse;
function moveAnimal(animal: Animal) {
let speed;
switch (animal.type) {
case "bird":
speed = animal.flyingSpeed;
break;
case "hourse":
speed = animal.runningSpeed;
break;
}
console.log("이 동물의 속도는 " + speed + "입니다.");
}
const bird: Animal = {
type: "bird",
flyingSpeed: 30,
};
moveAnimal(bird);
4. 타입 캐스팅(Type Casting)
타입 캐스팅은 강제 형변환이라고 한다.
만약 DOM에 대해서 다뤄야할 때 아래의 코드와 같이 쓴다면,
오류가 난다.
전제: HTML에 input1이라는 아이디의 input 태그가 있을 때
//typescript
const inputEl = document.getElementById('input1');
console.log(inputEl.value);
/*
------오류 메시지------
const inputEl: HTMLElement | null
개체가 'null'인 것 같습니다.
------------------------
*/
//1차적 해결 null이 아니라고 !키워드 쓰기
const inputEl = document.getElementById('input1')!;
console.log(inputEl.value);
/*
-----오류 메시지------
'HTMLElement' 형식에 'value' 속성이 없습니다.
----------------------
*/
이러한 오류들이 뜨는데, 이런 오류를 뜨지 않게 하는 방법이 3가지가 있다.
1. 강제로 <HTMLInputElement>로 타입 설정하기(타입을 미리 알 때)
const inputEl = <HTMLInputElement>document.getElementById('input1')!;
console.log(inputEl.value);
2. as HTMLInputElement를 써서 강제로 타입 설정하기(타입을 미리 알 때)
const inputEl = document.getElementById('input1')! as HTMLInputElement;
console.log(inputEl.value);
3. 타입을 모를 때 타입가드 사용하기
const inputEl = document.getElementById("input1");
if(inputEl){
(inputEl as HTMLInputElement).value = "안녕하세요"
}
'관심있는 언어들 > TypeScript' 카테고리의 다른 글
[TypeScript] 제네릭(Generics) (0) | 2022.01.27 |
---|---|
[TypeScript] 고급 타입2 (0) | 2022.01.13 |