본 포스트는 인프런의 타입스크립트 입문-기초부터 실전까지 강의(링크)를 듣고 정리한 내용입니다.
// 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도 상속 가능
배열 내에 type이 여러 종류가 있는 경우
const arr: (number | string | boolean)[] = [1, 2, 3, 'a', 'b', 'c', true];
유니온 타입을 이용해 배열에 들어간 개체들의 타입을 추론해 union type으로 정의
- Typescript 작성 중에 오류를 확인하기 위해 실시간으로 동작
- VS Code의 IntelliSence가 동작하기 위해서도 사용
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를 사용할 때 많이 사용
<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) }
