TS가 타입을 추론하는 방식 : 값 고려 → 값이 존재하는 곳의 문맥 고려
문맥을 고려해 타입 추론 시 종종 이상한 결과 발생
→ 타입 추론에 문맥이 어떻게 사용되는지 이해함으로써 대처
// 인라인 형태
setLanguage('Javascript');
// 참조 형태
let language = 'Javascript';
setLanguage(language);
// 타입스크립트에서의 리팩터링
function setLanguage(language: string) { /* ... */}
setLanguage('Javascript'); // 정상
let language = 'Javascript';
setLanguage(language); // 정상
인라인 형태에서 TS는 함수 선언을 통해 매개변수가 Language 타입임을 알고 있음
이 값을 변수로 분리해내면, TS는 할당 시점에 타입 추론
type Language = 'JavaScript' | 'TypeScript' | 'Python';
function setLanguage(language: Language) {
console.log(language);
}
setLanguage('JavaScript') // inline
let language = 'JavaScript';
setLanguage(language); // variable
// ~~~~~~~~ 'string' 형식의 인수는 'Language' 형식의 매개변수에 할당될 수 없습니다.
: string
으로 추론 → Language
타입으로 할당이 불가능하므로 오류 발생
타입 선언에서 language
의 가능한 값을 제한
let language: Language = 'Javascript';
setLanguage(language); // 정상
language
를 상수로 만드는 방법
const language = 'Javascript';
setLanguage(language); // 정상
문맥으로부터 값을 분리함 → 근본적 문제 발생의 원인이 됨
해당 문제의 발생 원인 :
const
는 얕게(shallow) 동작하기 때문
function panTo(where: [number, number]){
console.log(where);
}
panTo([10, 20]); // inline
const loc = [10, 20]; // 문맥에서 값 분리
panTo(loc);
loc
는 문맥에서 값을 분리하여 할당 시점에 number[]
(길이를 알 수 없는 숫자의 배열)로 추론됨
// 1. any를 사용하지 않고 오류를 고칠 수 있는 방법
const loc: [number, number] = [10, 20];
panTo(loc); // 정상
// 2. '상수 문맥'을 제공하는 방법
const loc = [10, 20] as const;
panTo(loc);
// ~~~ 'readonly [10,20] 형식은 'readonly'이며
// 변경 가능한 형식 '[number, number]'에 할당할 수 없습니다.
1번 방식 : const
는 단지 값이 가리키는 참조가 변하지 않는 얕은(shallow) 상수
2번 방식 : as const
는 그 값이 내부까지(deeply) 상수
라는 사실을 TS에 알려줌
any
를 사용하지 않고 오류를 고칠 수 있는 최선의 해결책 : panTo
함수에 readonly
구문 추가
function panTo(where: readonly [number, number]){
console.log(where)
}
const loc = [10, 20] as const;
panTo(loc);
문맥에서 값을 분리하는 문제 : 큰 객체에서 상수를 뽑아낼 때도 발생
type Language = 'JavaScript' | 'TypeScript' | 'Python';
interface GovernedLanguage {
language: Language;
organization: string;
}
function complain(language: GovernedLanguage) {
console.log(language.language);
}
complain({language : 'JavaScript', organization: 'Microsoft'});
const ts = {
language : 'JavaScript',
organization: 'Microsoft'
}
complain(ts);
ts
객체에서의 language
타입은 string
으로 추론
→ 타입 선언 추가(const ts: GoveredLanguage = …
) or 상수 단언(as const
)으로 해결
콜백을 다른 함수로 전달 시, TS는 콜백의 매개변수 타입 추론을 위해 문맥 사용
function callWithRandomNumbers(fn: (n1: number, n2: number) => void) {
fn(Math.random(), Math.random());
}
callWithRandomNumbers((a, b) => {
console.log(a + b); // a, b type : number
})
const func = (a, b) => {
console.log(a + b); // a, b type : any
}
callWithRandomNumbers(func);
해당 경우는 매개변수에 타입 구문을 추가해 해결 가능
const func = (a: number, b: number) => {
console.log(a + b);
}
type callback = (a: number, b: number) => void;
const func2: callback = (a, b) => {
console.log(a + b);
}
as const
) 사용