3주차 Item 19 ~ 27
타입스크립트가 타입을 추론할 수 있다면 타입 구문을 작성하지 않는게 좋다.
이상적인 경우 함수의 시그니처에는 타입 구문이 있지만, 함수 내의 지역변수에는 타입 구문이 없다.
내부 구현의 오류가 사용자 코드 위치에 나타내는 것을 방지하기 위해 추론될 수 있는 경우라도 객체 리터럴과 함수 반환에는 타입 명시를 고려해야 한다.
자바스크립트에서 let 키워드로 변수를 선언한다면 값은 바뀔 수 있지만 타입은 일반적으로 바뀌지 않는다.
혼란을 막기 위해 타입이 다른 값을 다룰 때에는 변수를 재사용하지 않고 되도록 const로 변수를 선언한다.
// 명시적 타입 구문 제공
const v = {
x: 1,
} // 타입 : { x: number }
v.x = 3;
v.x = '3'; // 오류 발생
const v: { x: 1|3|5 } = {
x: 1,
} // 타입 : { x: 1|3|5 }
// const 단언문 사용
const v1 = {
x: 1,
y: 2,
} // 타입 : { x: number, y: number }
const v2 = {
x: 1 as const,
y: 2,
} // 타입 : { x: 1, y: number }
const v3 = {
x: 1,
y: 2,
} as const // 타입 : { readonly x: 1; readonly y: 2; }
const a1 = [1, 2, 3]; // 타입 : number[]
const a2 = [1, 2, 3] as const; // 타입 : readonly [1, 2, 3]
const el = doument.getElementById('foo'); // 타입 : HTMLElement | null
if (el) {
// 타입 : HTMLElement
} else {
// 타입 : null
}
interface UploadEvent { type: 'up'; ... }
interface DonwloadEvent { type: 'donw'; ... }
type AppEvent = UploadEvent | DonwloadEvent;
function handleEvent(e: AppEvent) {
switch (e.type) {
case 'down':
e // 타입 : DonwloadEvent
break;
case 'up':
e // 타입 : UploadEvent
break;
}
}
타입스크립트에서 객체는 속성을 제각각 추가하지말고 한꺼번에 만들어야한다.
안전한 타입으로 속성을 추가하려면 객체 전개({...a, ...b})를 사용해야한다.
객체 전개를 통해 속성을 추가할때 여러 속성을 추가할 경우 헬퍼 함수를 적절하게 사용하지 않는다면 타입이 유니온으로 추론된다.
function addOptional<T extends object, U extends object>(
a: T, b: U | null
): T & Partia<U> {
return {...a, ...b};
}
별칭은 타입스크립트가 타입을 좁히는 것을 방해한다. 따라서 변수에 별칭을 사용할 떄는 일관되게 사용해야 한다.
비구조화 문법을 사용하는 것이 일관된 이름을 사용하는데 도움을 준다.
함수 호출이 객체 속성의 타입 정제를 무효화할 수 있다는 점을 주의해야 한다. 속성보다 지역 변수를 사용하면 타입 정제를 믿을 수 있다.
코드 퀄리티 뿐만아니라 타입 추론 면에서 콜백보다는 프로미스를 프로미스보다는 async/await를 사용하는 것이 좋다.
어떤 함수가 프로미스를 반환한다면 async로 선언하는 것이 좋다.
type A = 'JavaScript';
function setA(a: A) { /*...*/ }
setA('JavaScript') // 정상
let aa = 'JavaScript';
setA(aa); // 오류
const bb = 'JavaScript';
setA(bb); // 정상
이는 const(상수 변수 선언 키워드)를 사용해 해결 할 수 있다.
문자열 리터럴 타입과 마찬가지로 튜플 타입에서도 문제가 발생한다.
function panToBefore(a: [number, number]) { /*...*/ }
panToBefore([1, 2]); // 정상
const loc = [1, 2];
panToBefore(loc); // 오류
// -----------------------------------------------------------
function panToAfter(a: readonly [number, number]) { /*...*/ }
const loc = [1, 2] as const
panToAfter(loc); // 정상
JavaScript에서 배열 안의 객체들의 값을 handling(배열, 객체 및 문자열 반복 / 복합적인 함수 생성) 할 때 유용한 라이브러리