타입 추론 vs. 명시적으로 타입 선언 (🤔)
타입 추론이 되도 명시적으로 타입 선언할 경우에서의 기능상 이점은 동일하다.
일관성있게 작성하려면 타입을 전부다 선언해준다.
const b = '나는 문자'; // string
function getA(b = 10) { // b: number => number
const c = '문자';
return b + c; // string + number => string으로 추론
}
const arr = [0, 1, null]; // number[]
const arr2 = [0, 1, true]; // (number | boolean)[]
[something] as [type], 타입을 단언하다.
const div = document.querySelector('div'); // null | HTMLDivElement
if (div) {
div.innehrText;
}
strict 모드에서 element의 타입은 null | HTMLDivElement이다.
이 때문에 element의 속성에 접근하려면 null인지 확인해줘야하는 작업이 필수적이다.
하지만, element가 null이 아님을 개발자가 보장할 수 있다면 타입 단언을 사용해서 null인지 확인하는 과정을 뺄 수 있다.
const div = document.querySelector('div') as HTMLDivElement; // HTMLDivElement
div.innehrText
interface Developer {
name: string;
skill: string;
}
interface Person {
name: string;
age: number;
}
function introduce(): Developer | Person {
return { name: 'Tony', age: 33, skill: 'Iron Making'; }
}
const tony = introduce(); // Developer | Person
tony는 Developer | Person 타입을 가지며 유니온 연산에 따라서 name 속성만을 가지고 있다.
skill에 접근하려면 어떻게 해야할까?
타입 가드를 정의하고 함수가 원하는 타입을 가진 값을 반환하도록 한다.
function introduce(): Developer | Person {
return { name: 'Tony', age: 33, skill: 'Iron Making'; }
}
// 타입 가드 정의
function isDeveloper (target: Developer | Person): target is Developer {
return 'skill' in target;
}
const tony = introduce(); // Developer | Person
if (isDeveloper(tony)) {
// tony is Developer
tony.skill;
} else {
// ...
}
타입 가드 정의 없이 if (‘skill’ in target)... 이런 식으로 꺼내서 작성해도되겠지만,
정의를 하는 방식은 재활용을 할 수 있으면서도 가독성이 더 좋은 것 같다.
아래처럼 string, string[]말고도 number, bigint, boolean, undefined, object, function, symbol와도 typeof을 이용해 비교할 수 있다. ( *null 값은 object 타입)
function printAll(strs: string | string[]) {
if (typeof strs === string) {
console.log(strs);
return;
}
console.log(strs.join(''));
}
구조적 타이핑 - 코드 구조 관점에서 타입이 서로 호환되는지 여부를 판단
interface Flower {
name: string;
}
let tulip: Flower;
let prizia = { name: '프리지아', age: 13 };
tulip = prizia; // 호환가능
prizia = tulip; // 호환 불가능(age 속성이 없어서 )
class 간의 비교시 스태틱 멤버, 생성자를 제외한 속성만을 비교
구조적 타이핑으로 타입을 비교하므로, 아래와 같이도 작성할 수 있다.
interface Flower {
name: string;
}
class Prizia {
name: string;
age: number;
}
const prizia: Flower = new Prizia();
let add = function(a: number) {
// ...
}
let sum = function(a: number, b: number) {
// ...
}
add = sum; // 호환 불가능, add함수는 a매개변수 하나만 필요함.
sum = add; // 호환 가능