'is', 'as' 문법 정리

신태일·2024년 10월 16일

💡 기존에 alias용도로 as를 사용하기 시작하다가 조금은 정리가 좀 필요할 것 같아서 정리하려는 찰나에 is 키워드도 알게되면서 덩달아 정리해보려고 한다.

const instanceOfToDo = (object: any): object is IToDo => {
	return (
		object.constructor === Object &&
		"id" in object &&
		"text" in object &&
		typeof (object as IToDo).id === "number" &&
		typeof (object as IToDo).text === "string"
	);
};

‘as’ 키워드란? [type assertion]


as 키워드는 컴파일러가 객체를 추론하는 유형이 아닌 다른 유형으로 객체를 고려하도록 컴파일러에 지시하는 TypeScript의 유형 어설션입니다.

위 인용은 docs 문서를 번역한것이다. 요약하자면 ‘컴파일’ 단계에서 타입 검사를 할 때 타입스크립트가 감지하지 못하는 애매한 타입 요소들을 직접 명시해주는 키워드라고 볼 수 있다. 예를 들어 아래와 같은 코드가 있다고 하자.

const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement;

이 코드에서 as HTMLCanvasElement 부분이 없다고 가정한다면, 타입스크립트는 그저 myCanvas가 여러 HTMLElement 중 어느 하나의 HTMLElement만을 가질 것이란 사실 밖에 알지 못한다. 이러한 경우에 as HTMLCanvasElement를 적어줌으로써 myCanvasHTMLCanvasElement를 가진다는 것을 알게 되며 에러의 확률을 줄일 수 있게 된다.

위 코드는 as 키워드를 사용하지 않고도 표현할 수 있는데, tsx 파일 내에 있다고 가정하고 아래와 같이 쓸 수 있다.

const myCanvas = <HTMLCanvasElement>document.getElementById("main_canvas");

한 가지 특징은 as 키워드(type assertion)은 오직 컴파일 단계에서만 실행되며 런타임 단계에서는 삭제된 채로 실행된다. 컴파일 단계에서 제대로 넘어갔다면 런타임 단계에서의 에러 발생은 일어나지 않는다는 말이다.

‘is’ 키워드란? [type guard]

function isString(test: any): test is string{
	return typeof test === "string";
}

function example(foo: any) {
	if (isString(foo)) {
		console.log("it is a string" + foo);
		console.log(foo.length); // string function
	}
}

example("hello world");

isString() 함수를 살펴보면 return 문의 값이 true일 때, test is string이란 type predicate 구문이 있기 때문에 타입스크립트는 이 함수를 호출한 범위 내에서 isString()의 결과 타입을 string으로 좁힌다.

그러니까 isString() 함수를 거쳐서 return 값이 true라면, type predicate에 적은 말 그대로 ‘함수가 호출된 범위 내에선 test를 string 타입으로 보라’ 는 것이다. 위 as 키워드와 마찬가지로 is 키워드 역시 컴파일 단계에서만 사용되며 런타임 단계에서는 순수한 js 파일과 동일하게 동작한다.

E.g 1

아래의 코드는 컴파일 그리고 런타임 단계에서 에러가 발생하는데, 그 이유는 타입스크립트가 foo의 타입을 string으로 좁혀놓은 상태에서 toExponential() 함수가 string 메소드에 속하지 않는다는 에러를 체크하기 때문이다.

function example(foo: any) {
	if (isString(foo)) {
		console.log("it is a string" + foo);
		console.log(foo.length);
		console.log(foo.toExponential(2)); // Error! 이미 string으로 좁혀놨는데 Number의 메소드를 시도하고 있다.
	}
}

결론

  • as 키워드는 Type Assertion(타입 단언)으로, 컴파일 단계에서 타입스크립트가 잘못 혹은 보수적으로 타입을 추론하는 경우 개발자가 수동으로 컴파일러에게 특정 변수에 대한 타입 힌트를 주는 것이다.
  • is 키워드는 Type Guard(타입 가드)로, as가 특정 변수 하나에 국한된 것이라면 is 키워드는 한정된 범위 내의 모든 변수에 대해서 일괄적으로 적용할 수 있는 키워드이다.
profile
노원거인

0개의 댓글