kind를 통해 분류해보자.
never type
Exhaustiveness checking pattern
이전까지는 순수한 JS 문법만을 사용해서 narrowing을 진행하였다.
하지만 쓸만한 TS 문법을 통해 narrowing을 좀 더 구체적으로 해줄 수 있다.
아래의 예제는 kind를 사용하여 함수의 인자를 가려 받아 에러 발생의 여지를 줄인
함수이다.
interface Circle{
kind: "circle";
radius:number;
}
interface Square{
kind:"square";
sideLength:number;
}
type Shape=Circle | Square;
function handleShape(shape:Shape){
if(shape.kind==='circle'){
console.log('radius: ',Math.PI*shape.radius ** 2);
}else if(shape.kind==='square'){
console.log('surface: ', shape.sideLength ** 2);
}
}
handleShape({kind:'circle',radius:2});
kind를 사용하여 외부에 직접적으로 나타나지는 않지만 오로지 literal type을 지정해주기 위한 용도로
interface
내부에 kind가 자리잡게 되었다.
if로 구분할 수 있으니 당연히 case
문을 사용하여 구분해줄 수 있다.
function handleShapeCase(shape:Shape){
switch (shape.kind){
case 'circle':
return Math.PI * shape.radius ** 2;
case 'square':
return shape.sideLength ** 2;
}
}
const lab:Circle={
kind:'circle',
radius:5,
}
console.log(handleShapeCase(lab));
이런식으로 작성해주는 방법이 있다.
never type은 narrowing을 하는 도중에 해당 파라메터의 자리에 들어가는 것을 방지하기 위한
방법 중 하나이다. 바로 예를 보며 확인하자.
interface Circle{
kind: "circle";
radius:number;
}
interface Square{
kind:"square";
sideLength:number;
}
type Shape=Circle | Square;
function handleShapeCase(shape:Shape){
switch (shape.kind){
case 'circle':
return Math.PI * shape.radius ** 2;
case 'square':
return shape.sideLength ** 2;
default:
const _exCheck: never = shape;
return _exCheck;
}
}
const lab:Circle={
kind:'circle',
radius:5,
}
console.log(handleShapeCase(lab));
아래의 코드를 보면 default 값으로
default:
const _exCheck: never = shape;
return _exCheck;
값이 추가 되었는데 변수 하나를 선언하고 타입을 never로 선언하여 파라메터로 초기화한다.
interface Circle{
kind: "circle";
radius:number;
}
interface Square{
kind:"square";
sideLength:number;
}
interface Triangle{
kind:"triangle";
sideLength:number;
}
type Shape=Circle | Square | triangle;
function handleShapeCase(shape:Shape){
switch (shape.kind){
case 'circle':
return Math.PI * shape.radius ** 2;
case 'square':
return shape.sideLength ** 2;
default:
const _exCheck: never = shape; // err
return _exCheck;
}
}
const lab:Circle={
kind:'circle',
radius:5,
}
console.log(handleShapeCase(lab));
위 예제처럼 default에서는 선언되지 않은 예외 상황을 모두 무시한다고 한다.
즉 사용하고 싶다면 case를 통해 선언하고 이를 사용하라는 말이며
공동작업을 한다면 위 처럼 타입 검사를 철저하게 하여 에러를 방지해줄 수 있다.