✔ 콜백보다 프로미스나 async/await를 사용해야 하는 이유
function timeout(millis: number): Promise<never> {
return new Promise((resolve, reject) => {
setTimeout(() => reject("timeout"), millis);
});
}
async function fetchWithTimeout(url: string, ms: number) {
return Promise.race([fetch(url), timeout(ms)]);
}
타입구문이 없어도 fetchWithTimeout의 반환 타입은 Promise로 추론된다.
프로미스를 사용하면 타입스크립트의 모든 타입 추론이 제대로 동작한다
✔ 프로미스를 생성하기보다는 async/await를 사용해야 하는 이유
❗ async 함수에서 프로미스를 반환하면 또 다른 프로미스로 래핑되지 않는다. 반환 타입은 Promise<Promise<T>>가 아닌 Promise<T>
가 된다.
type Language = "Javascript" | "Typescript";
function setLanguage(language: Language) {
/* ... */
}
setLanguage("Javascript"); // 정상
let language = "Javascript";
setLanguage(language); // ❌ 'string' 형식의 인수는 'Language'형식의 매개변수에 할당될 수 없습니다.
'Javascript' 값을 변수로 분리해내면, 타입스크립트는 할당 시점에 타입을 추론한다. 위와 같은 경우는 string으로 추론했고, Language 타입으로 할당이 불가능하므로 오류가 발생한다.
👉 해결방법
let language: Language = "Javascript";
setLanguage(language); // 정상
const language = "Javascript";
setLanguage(language); // 정상
language는 변경할 수 없다고 알려줌으로써 타입스크립트는 language에 대해서 더 정확한 타입인 문자열 리터럴 'Javascript'로 추론이 가능하다.
✔ 튜플 사용 시 주의점
function panTo(where: [number, number]) {
/* ... */
}
panTo([1, 2]); // 정상
const loc = [1, 2];
panTo(loc); // ❌ 'number[]' 형식의 인수는 '[number, number]' 형식의 매개변수에 할당될 수 없습니다.
타입스크립트가 loc의 타입을 number[] 로 추론(길이를 알 수 없는 숫자의 배열)하기 때문에 발생한 에러
👉 해결방법
const loc: [number, number] = [1, 2];
panTo(loc); // 정상
const loc = [1, 2] as const;
panTo(loc); // ❌ 'readonly [1,2]' 형식은 'readonly'이며 변경 가능한 형식 '[number, number'에 할당할 수 없습니다.
function panTo(where: readonly [number, number]) {}
const loc = [1, 2] as const;
panTo(loc); // 정상
✔ 객체 사용 시 주의점
type Language = "Javascript" | "Typescript";
interface GovernedLanguage {
language: Language;
organization: string;
}
function complain(language: GovernedLanguage) {
/* ... */
}
complain({ language: "Typescript", organization: "Microsoft" }); // 정상
const ts = {
language: "Typescript",
organization: "Microsoft",
};
complain(ts); // ❌ 에러
ts 객체에서 language의 타입은 string으로 추론된다. 타입 선언을 추가하거나 상수 단언을 사용하여 해결할 수 있다.
✔ 콜백 사용 시 주의점
function callWithRandom(fn: (n1: number, n2: number) => void) {
fn(Math.random(), Math.random());
}
callWithRandom((a, b) => {
a; // type: number
b; // type: number
console.log(a + b);
});
const fn = (a, b) => {
console.log(a + b); // ❌ 'a', 'b' 매개변수에는 암시적으로 'any' 형식이 포함됩니다.
};
callWithRandom(fn);
const fn = (a: number, b: number) => {
console.log(a + b);
};
callWithRandom(fn); // 정상
변수를 뽑아서 별도로 선언했을 때 오류가 발생한다면 타입 선언을 추가해야 한다.