[TS] 타입 추론, 타입 단언, 타입 가드
작성:    
업데이트:
카테고리: TS Basic
태그: FE Language, TS, TS Basic
본 포스트는 인프런의 타입스크립트 입문-기초부터 실전까지 강의(링크)를 듣고 정리한 내용입니다.
타입 추론(Type Inference)
타입 추론이란?
// parameter의 type으로 return 값의 type이 결정
function getB(b) {
return b;
}
// parameter의 type으로 return 값의 type이 결정
function getB(b) {
const c = 'hi'
return b + c;
}
- number + string = string으로 type 추론
- return 값이 내부적으로 string으로 추론
인터페이스와 제네릭에서의 타입 추론
인터페이스와 제네릭
interface Dropdown<T> {
value: T;
title: string;
}
const shoppingItem: Dropdown<string> = {
value: 'abc',
title: 'hello',
}
인터페이스의 상속
interface Dropdown<T> {
value: T;
title: string;
}
// 관행적으로 T를 쓰지만 구분을 위해 K 사용
interface DetailedDropdown<K> extends Dropdown<K> {
description: string
tag: K;
}
const detailedItem: DetailedDropdown<string> = {
value: 'abc',
title: 'hello',
description: '안녕하세요~~',
tag: 'a'
}
인터페이스 A를 상속받은 인터페이스 B는 generic의 Type도 상속 가능
Best Common Type
배열 내에 type이 여러 종류가 있는 경우
const arr: (number | string | boolean)[] = [1, 2, 3, 'a', 'b', 'c', true];
유니온 타입을 이용해 배열에 들어간 개체들의 타입을 추론해 union type으로 정의
Typescript Language Server
- Typescript 작성 중에 오류를 확인하기 위해 실시간으로 동작
- VS Code의 IntelliSence가 동작하기 위해서도 사용
타입 단언(Type Assertion)
타입 단언의 필요성
let a;
a = 20;
a = 'a';
let b = a;
- any였던 a가 중간의 코드를 거치며 type이 확정
- 하지만 이후의 a를 참조하는 b는 a의 중간 코드를 모르므로, 처음에 선언했던 any type으로 지정
let a;
a = 20;
a = 'a';
let b = a as string;
- “TS보다 개발자가 더 코드를 잘 알고 있다! 그러니 내가 지정한대로 해라!”
- DOM API를 사용할 때 많이 사용
DOM API와 타입 단언
<div id="app">hi</div>
const app = document.querySelector('#app');
- app의 type은 HTMLDivElement
- 하지만 실무에서는 이렇게 깔끔하게 펼쳐지지 않는다.
- HTMLDivElement일 수도 있지만 null 일 수도 있다는 의미!
HTMLDivElement임을 증명하자
const div = document.querySelector('div') as HTMLDivElement;
if (div) {
div.innerText;
}
- HTMLDivElement가 확실하다고 개발자가 전달
- HTMLDivElement에서 지원하는 DOM API 사용 가능
타입 가드
타입 가드의 필요성
interface Developer {
name: string;
skill: string;
}
interface Person {
name: string;
age: number;
}
function introduce(): Developer | Person {
return { name: 'Tony', age: 33, skill: 'Iron Making' }
}
- 위의 두 interface로 정의된 introduce 함수의 반환값은 두 interface의 union type
- tony는 name만 접근할 수 있다. 두 interface에 공통으로 존재하기 때문!
- 반대로 생각하면 tony가 Developer interface인데 Person interface의 속성을 쓰면 안되기 때문
const tony = introduce();
if ((tony as Developer).skill) {
const skill = (tony as Developer).skill;
console.log(skill);
} else if ((tony as Person).age) {
const age = (tony as person).age;
console.log(age);
}
- tony의 두 interface type에 대하여 타입 단언으로 있으나 없으나 사용
- 없으면 if문에서 걸러지고, 있으면 if문 내부에서 사용 가능
좀 더러운데요?
- 타입단언 코드도 반복되고 좀 더럽긴 하다.
타입 가드의 활용
function isDeveloper(target: Developer | Person): target is Developer {
return (target as Developer).skill !== undefined;
}
- Developer일지, Person일지 모르는 target을 전달받음
- 이를 Developer로 간주하고 skill을 찍었을 때, Developer면 string, Person이면 undefined
- 만약 true이면 target을 Developer로 한다.
위의 함수를 사용해보자.
// if ((tony as Developer).skill) {
// const skill = (tony as Developer).skill;
// console.log(skill);
// } else if ((tony as Person).age) {
// const age = (tony as person).age;
// console.log(age);
// }
if(isDeveloper(tony)) {
console.log(tony.skill)
} else {
console.log(tony.age)
}
댓글남기기