narrowing with kind & never

YOUNGJOO-YOON·2021년 7월 5일
0

typeScript

목록 보기
17/65

TOC

  1. kind를 통해 분류해보자.

  2. never type

  3. 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));

이런식으로 작성해주는 방법이 있다.

2. never type

never type은 narrowing을 하는 도중에 해당 파라메터의 자리에 들어가는 것을 방지하기 위한
방법 중 하나이다. 바로 예를 보며 확인하자.


3. Exhaustiveness checking pattern


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를 통해 선언하고 이를 사용하라는 말이며
공동작업을 한다면 위 처럼 타입 검사를 철저하게 하여 에러를 방지해줄 수 있다.

profile
이 블로그의 글은 제 생각을 정리한 글과 인터넷 어딘가에서 배운 것을 정리한 글입니다. 출처는 되도록 남기도록 하겠습니다. 수정 및 건의 오류 등이 있으면 언제든지 댓글 부탁드립니다.

0개의 댓글