변수 혹은 매개변수 등이 string이나 number처럼 어떠한 포괄적인 타입을 가지는 것이 아니라 변수나 매개변수에 정확한 값을 설정하는 것이다.
//아래 코드에서 Food에서 허용한 3개의 문자열 외에 다른 문자열을 사용하게 되면 에러가 발생한다.
type Food = "rice" | "noodle" | "meat";
const myFood1: Food = "rice";
const myFood2: Food = "aaa"; // Error: Type 'aaa' is not assignable to type 'Food'.
type Grade = 1 | 2 | 3;
const student1: Grade = 1;
const student2: Grade = 5; // Error: Type '5' is not assignable to type 'Grade'.
var, let으로 변수를 선언하면 이 변수의 값이 변경될 가능성이 있음을 컴파일러에게 알린다. 반면, const를 사용해서 변수를 선언하면 값이 절대 변하지 않는다는 것을 컴파일러에게 알린다.
// const를 사용해서 변수가 절대 변경되지 않음을 보장한다.
const helloWorld = "Hello World";
// let은 변경될 수 있으므로 컴파일러는 문자열이라고 선언 할 것이다.
let helloWorkd = "Hello World";
유니온 타입(Union Type)이란 자바스크립트의 OR 연산자(||)
와 같이 'A' 이거나 'B'이다
라는 의미의 타입이다.
//함수의 파라미터 text에는 문자열 타입이나 숫자 타입이 모두 올 수 있다.
//이처럼 | 연산자를 이용하여 타입을 여러 개 연결하는 방식을 유니온 타입 정의 방식이라고 부른다.
function logText(text: string | number) {
// ...
}
이 예제에서, Bird
는 fly
라는 멤버를 갖고 있다. Bird | Fish
로 타입이 지정된 변수가 fly
메서드를 가지고 있는지 확신할 수 없다. 만약 변수가 실제로 런타임에 Fish이면, pet.fly()
를 호출하는 것은 오류이다.
interface Bird {
fly(): void;
layEggs(): void;
}
interface Fish {
swim(): void;
layEggs(): void;
}
declare function getSmallPet(): Fish | Bird;
let pet = getSmallPet();
pet.layEggs();
// 두 개의 잠재적인 타입 중 하나에서만 사용할 수 있습니다.
pet.swim(); //error
유니언을 사용하는 데 있어서 일반적인 기술은 TypeScript가 현재 가능한 타입 추론의 범위를 좁혀나가게 해줄 수 있는 리터럴 타입을 갖는 단일 필드를 사용하는 것이다.
state
필드가 NetworkState
안의 모든 타입에 공통으로 존재한다는 점을 안다면 존재 여부를 체크하지 않고도 접근할 수 있다.
type NetworkLoadingState = {
state: "loading";
};
type NetworkFailedState = {
state: "failed";
code: number;
};
type NetworkSuccessState = {
state: "success";
response: {
title: string;
duration: number;
summary: string;
};
};
type NetworkState =
| NetworkLoadingState
| NetworkFailedState
| NetworkSuccessState;
function networkStatus(state: NetworkState): string {
// 현재 TypeScript는 셋 중 어떤 것이
// state가 될 수 있는 잠재적인 타입인지 알 수 없습니다.
// 모든 타입에 공유되지 않는 프로퍼티에 접근하려는 시도는
// 오류를 발생시킵니다.
state.code;
// state에 swtich문을 사용하여, TypeScript는 코드 흐름을 분석하면서
// 유니언 타입을 좁혀나갈 수 있습니다.
switch (state.state) {
case "loading":
return "Downloading...";
case "failed":
// 여기서 타입은 NetworkFailedState일 것이며,
// 따라서 `code` 필드에 접근할 수 있습니다.
return `Error ${state.code} downloading`;
case "success":
return `Downloaded ${state.response.title} - ${state.response.summary}`;
}
}
교차 타입(Intersection Type)은 여러 타입을 모두 만족하는 하나의 타입을 의미한다.
예를 들어 type D = A & B & C & 와 같은 타입을 정의하면 D는 A, B , C의 속성 모두를 가진다.
interface Person {
name: string;
age: number;
}
interface Developer {
name: string;
skill: number;
}
type Capt = Person & Developer;
let person: Capt = {
name : "tony",
age : 5,
skill: 5
}
교차 타입의 경우 동일한 키 값의 서로 다른 타입이 있는 경우 never 타입으로 바꿔버리는 것을 볼 수 있다.
type Animal1 = {
howl: number;
};
type Animal2 = {
howl: string;
};
type animal1 = Animal1 | Animal2;
type animal2 = Animal1 & Animal2;
let test1: animal1 = {
howl: "animallll",
};
// error : 'number' 형식은 'never' 형식에 할당할 수 없습니다.
let test2: animal2 = {
howl: 123
};