타입 좁히기는 함수 안에 여러 유형의 타입이 들어왔을 경우 조건문을 사용해 해당 타입을 좁혀서 보다 안전한 코드를 작성하도록 한다.
function func(x:number | string){
if(typeof x === 'number'){
x.toFixed() //number 타입이라 가능하다.
}
if(typeof x === 'string'){
x.toUpperCase() //string 타입이라 가능하다.
}
}
타입 스크립트는 8가지 항목에 대해서 타입 가드를 수행한다.
typeof
는 null
문자열을 반환하지 않는다는 것을 명심해야 한다.
function printAll(str: string | string[] | null){
if(typeof strs === "object"){
for(const s of strs){
'strs' is possibly 'null'
console.log(s);
}
} else if (typeof strs === 'string'){
console.log(strs);
}else{
//do nothing
}
}
printAll 함수에서는 strs 가 객체인지 확인하여 배열 타입인지 확인하려고 한다. 그러나 JavaScript에서는 typeof null이 실제로 "object"를 나타내는 것이 문제.
때문에 typeof는 주로 원시타입을 좁히는 용도로 사용하는 것을 권장한다.(위의 type guard 목록)
interface Range {
start: Date;
end: Date;
}
interface DatePickerProps {
selectedDates?: Date | Range;
}
const DatePicker = ({ selectedDates }: DatePickerProps) => {
const [selected, setSelected] = useState(convertToRange(selectedDates));
// ...
};
export function convertToRange(selected?: Date | Range): Range | undefined {
return selected instanceof Date
? { start: selected, end: selected }
: selected;
}
위 코드와 같이 instanceof를 활용해서 특정 객체가 특정 클래스에 속하는지 판별하여 축소할 수 있다.
function isString(value: any): value is string {
return typeof value === 'string';
}
is는 typescript에서 지원하고 있는 키워드이며, 특정 타입을 체크하는 함수에서 반환되는 값이 true이면 해당 함수를 사용하는 블록 안에서도 같은 타입으로 확정시켜줄 수 있는 기능을 한다.