일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- bucket4j
- 스프링부트
- Dev-Matching
- 프리코스
- this
- redis
- 음악 url 파일 다운로드
- 프로그래머스
- api 비동기처리
- TypeORM
- NestJS
- invalid_grant
- 타입스크립트
- 자바스크립트
- api 요청 수 제한
- 유효시간 설정 url
- 검색
- 모던 자바스크립트
- 프론트엔드
- AWS
- 딥다이브
- oauth
- 우아한테크코스
- Deep Dive
- 프론트엔드 과제
- 우아한 테크코스
- compateto
- 코멘토 #코멘토실무PT #실무PT후기 #실무강의 #리액트강의 #웹프로그래밍 #react #웹개발실무
- concurrency limit
- 파일 url
- Today
- Total
개발 알다가도 모르겠네요
타입스크립트의 타입 추론 본문
let bool = true;
const arr = [1, 2, 3];
const tuple = [true, 1];
bool = 1; // Error!
아래의 tuple 변수는 배열의 요소가 각각 boolean과 number이기에 최종적으로 추론되는 타입은 boolean과 number의 유니온 타입의 배열, 코드로 나타내면 (boolean | number)[]이 됩니다.
여기에서 배열에서 사용된 요소들의 타입을 각각 추론하여 유니온 타입으로 만들어 내는 방식을 Best common type이라고 부릅니다.
Best common type
Best common type 은 말 그대로 가장 일반적인 타입입니다.
여러가지 자료형이 배열 내부에서 사용되고 있을 때, 그 여러가지 자료형을 포괄할 수 있는 가장 일반적인 자료형을 추론하는 것입니다.
그 결과로 위의 예제에서는 true와 1을 포괄할 수 있는 자료형인, (boolean | number)가 추론된 것입니다.
class Parent {
foo = '';
}
class Child extends Parent {
bar = '';
}
const arr = [new Parent(), new Child()];
타입 단언(Type Assertion)
타입 단언은 TypeScript 컴파일러가 타입을 실제 런타임에 존재할 변수의 타입과 다르게 추론하거나 너무 보수적으로 추론하는 경우에 프로그래머가 수동으로 컴파일러한테 특정 변수에 대해 타입 힌트를 주는 것입니다.
class Character {
hp: number;
runAway() {
/* ... */
}
isWizard() {
/* ... */
}
isWarrior() {
/* ... */
}
}
class Wizard extends Character {
fireBall() {
/* ... */
}
}
class Warrior extends Character {
attack() {
/* ... */
}
}
function battle(character: Character) {
if (character.isWizard()) {
character.fireBall(); // Property 'fireBall' does not exist on type 'Character'.
} else if (character.isWarrior()) {
character.attack(); // Property 'attack' does not exist on type 'Character'.
} else {
character.runAway();
}
}
이 코드는 컴파일 에러를 내는데 Character 클래스에는 fireBall, attack 메소드가 선언조차 되어있지 않기 때문입니다.
타입 단언으로 적절한 타입을 다시 선언해주면,
function battle(character: Character) {
if (character.isWizard()) {
(character as Wizard).fireBall(); // Pass
} else if (character.isWarrior()) {
(character as Warrior).attack(); // Pass
} else {
character.runAway();
}
}
해당 변수가 실제로 Wizard 인스턴스가 아니더라도 as 키워드를 통해서 타입 단언을 해줄 수 있기 때문에, 타입 단언은 주의해서 사용해야 합니다.
실제로도 as any 라는 치트키로 대부분의 컴파일 에러를 해결할 수 있지만 as와 any는 가능한 적게 사용하는 것이 좋습니다.
<Type> vs as Type
타입 단언 문법은 <Type> 과 as Type 으로 두 종류가 있습니다.
(<Wizard>character).fireBall();
(character as Wizard).fireBall();
그냥 보기에는 <Type> 키워드가 좀 더 깔끔해보이지만, 대개 as Type 키워드가 추천됩니다.
React에서 JSX 를 사용하는 경우 <Type> 키워드는 JSX 의 문법과 겹치기 때문에 불편한 면이 있기 때문입니다.
타입 가드(Type Guard)
타입 가드는 타입 단언을 좀 더 깔끔하게 할 수 있도록 도와줍니다.
앞서 타입 단언에서 소개한 예제에서는 isWizard라는 메소드로 해당 인스턴스가 해당 타입이라는 사실을 확정했지만
이건 런타임에서만 알 수 있는 사실이고 TypeScript 컴파일러는 알 수 없습니다.
타입 가드는 이러한 런타임에서의 타입 체크를 컴파일러에게 알려주는 기능입니다.
이런식으로 런타임에서 실제 타입검사를 하는 메소드의 리턴타입으로 {variable} is {Type} 같은 문법을 사용해 선언해주면 됩니다.
class Character {
isWizard(): this is Wizard {
return this instanceof Wizard;
}
isWarrior(): this is Warrior {
return this instanceof Warrior;
}
}
'웹 > Typescript' 카테고리의 다른 글
타입스크립트의 Type Alias (0) | 2022.06.28 |
---|---|
타입스크립트의 타입 가드 (0) | 2022.06.27 |
타입스크립트의 Enum (0) | 2022.06.19 |
타입스크립트의 함수 (0) | 2022.06.18 |
타입스크립트의 인터페이스 (0) | 2022.06.18 |