→ 유니언과 내로잉은 다른 주요 프로그래밍 언어에서는 불가능, 타입스크립트에서만 가능한 ‘코드 정보에 입각한 추론’
* 유니언 : 이거 혹은 저거라고 생각(두 개 이상의 옵션이 가능한 경우)
* 유니언 타입 선언
→ 변수의 초기값이 있더라도 변수에 대한 명시적 타입 애너테이션 제공하는 것이 유용할 때 사용
→ 아래의 예시는 초기값이 null
이나 잠재적으로 string
이 될 수 있음 알려줌
→ 유니언 타입 선언은 타입 애너테이션으로 타입을 정의하는 모든 곳에서 사용 가능
let origin: string | null = null; //초기값 null
if(Math.random() > 0.5) {
origin = "브라질"
// origin = 1 -> 숫자는 오류
}
* 유니언 속성
→ 유니언으로 선언한 모든 가능한 타입에 존재하는 멤버 속성에만 접근 가능
▶ 안전조치 : 모든 유니언 타입에 존재하지 않는 속성에 대한 접근 제한
→ 객체가 어떤 속성인지 확실하지 않을 때, TS는 해당 속성을 사용하려고 시도하는 것이 안전하지 않다고 여김
→ 내로잉 사용 이유 : 유니언 타입으로 정의된 타입 값의 속성 사용 시 보다 구체적인 값을 알리기 위함
let physcist = Math.random() > 0.5 ? "Einstein" : 76;
physcist.toString();
//physcist.toUpperCase();
//-> number 타입에 없음
//physcist.toFixed();
//-> string 타입에 없음
* 값 할당을 통한 내로잉
→ 초기값이 주어질 때 할당 내로잉 적용
→ 변수가 나중에 유니언 타입으로 선언된 타입 중 하나의 값을 받을 수 있으나, 처음에는 초기에 할당된 값의 타입으로 시작함
let animal: number | string;
animal = "cat";
animal.toUpperCase(); //string
//animal.toFixed(); -> number와 string 중 string으로 값이 좁혀짐
→ if문을 통해 좁히는 방법이 일반적
let koreaCity = Math.random() > 0.5 ? "Seoul" : 50;
if(koreaCity = "Incheon") {
koreaCity.toUpperCase(); //string으로 값이 좁혀짐
}
//koreaCity.toUpperCase(); //string과 number 두 가지 값을 가짐
let singer = Math.random() > 0.5 ? "아이유" : 0;
typeof singer === "string" ? singer.toUpperCase() : singer.toFixed();
→ 원시 타입 값 중 어떤 것이 아닌 특정 원싯값으로 알려진 타입
→ 각 원시 타입은 해당 타입이 가질 수 있는 가능한 모든 리터럴 값의 조합으로 생각할 수 있음
const drama = "The glory";
// drama는 string 타입이면서 "The gloy"라는 특별한 값
* 리터럴 할당 가능성
→ name이나 string과 같은 서로 다른 원시 타입이 서로 할당되지 못함
→ 0과 1처럼 동일한 원시 타입이라고 해도 서로 다른 리터럴 타입은 서로 할당 불가
→ 하지만 리터럴 타입은 그 값에 해당하는 원타입 할당 가능
let character: "문동은";
character = "문동은";
//다른 값이 할당이 안 됨
//chracter = "박연진"; //Type '"박연진"' is not assignable to type '"문동은"'
let gloryname = ""; //string
gloryname = "문동은";
gloryname = "박연진";
gloryname = "주여정";
* 엄격한 null 검사 = 리터럴로 좁혀진 유니언의 중요성을 알게 됨, 잠재적으로 정의되지 않은 undefined값으로 작업할 때 더 잘 알 수 있음
→ null 또는 undefined값으로 인한 오류로부터 안전한지 여부를 쉽게 파악
let cafe = Math.random() > 0.5 ? "starbucks" : undefined;
//cafe.toLocaleLowerCase(); //string 뿐만 아니라 undefined도 가능하기 때문
* 참 검사를 통한 내로잉
→ 자바스크립트에서 참 또는 truthy(true)로 생각되는 값들은 많음
false, 0, -0, 0n, “”, null, undefined, NaN 제외한 모든 값이 참
let flower = Math.random() > 0.5 && "나팔꽃";
if(flower) {
flower; //타입 : string
} else {
flower; //타입: string | false
}
* 초기값이 없는 변수
→ 기본적으로 undefined
→ 타입스크립트는 값이 할당될 때까지 변수가 undefined임을 이해함
let drama: string | undefined;
drama?.length; //undefined도 포함되기 때문
drama = "The glory";
drama.length; //string
* 2개 혹은 3개 이상의 유니언 타입인 경우
→ 타입 별칭을 사용함
→ 예시의 값(boolean, number, string, null, undefined) 뿐만 아니라 array, function, object 타입도 가능함
type rawData = boolean | number | string | null | undefined;
let firstData: rawData;
firstData = false;
let secondData: rawData;
secondData = 10;
let thirdData: rawData;
thirdData = "데이터";
* 타입 별칭은 자바스크립트로 컴파일되지 않음
→ 타입 시스템에만 존재함
→ 개발 시에만 존재하며 런타임에서는 존재하지 않음
type SomeType = string | boolean;
//console.log(SomeType);
//'SomeType' only refers to a type, but is being used as a value here.
* 타입 별칭 결합
→ 다른 타입 별칭을 참조할 수 있음
type Id = number | string;
type IdMayby = Id | undefined | null; //IdMayby의 타입은 number, string, undefined, null