Share
Sign In
📄

Narrowing and Type Guard

타입스크립트에서 Narrowing을 하는 이유는, 각각의 타입을 입력받을 경우 어떻게 핸들링할 지를 정하여 예상치 못한 타입에 에러가 발생하는 것을 막기 위함이다.
동시에 type guard를 실현할 수 있는데, type guard가 무엇인지를 알아보기 위해 아래의 예를 살펴보자.
위의 문제는 type Assertion을 통해 해결할 수 있다.
이런 방법식은 코드가 지저분해지고, 가독성이 떨어지며 유지보수가 힘들게 한다. 이를 해결하기 위해 TypeScript도 해당 위치에 변수(또는 객체, 함수의 인자)가 어떤 타입을 갖고 있는지 알 필요가 있다. 이를 Type Guard 라고 한다.
Typeof operator narrowing
다양한 방법으로 Narrowing을 할 수 있고, 조심해야할 점이 있다. 이를 살펴보자.
원하는 타입으로 값이 입력되었는지 확인하기 위해, if문의 조건절 안에 typeof 연산자를 사용할 것이고, 그 결과로 아래의 값중 하나로 반환 받을 것이다.
"string"
"number"
"bigint"
"boolean"
"symbol"
"undefined"
"object"
"function"
이 방법 역시 좋은 방법이지만, 조심해야할 부점은 typeof null 의 결과 값도 object 이다. 객체 타입만( {} ) object 일 것이라 생각하지만, 배열도(typeof []) object 이다.
이를 해결하기 위해서 TypeScript 에서는 Truthiness narrowing 이라는 것을 제시했다,
Truthiness narrowing
실제로 존재하는 단어는 아니나, 익숙해지기 위해 붙인 단어이다.
JavaScript에서 if문의 조건절에서 아래의 경우를 제외하고는 모두 true로 강제된다.
0
NaN
""
0n (bigint 버전 0)
null
undefined
따라서 위의 경우에서 null 또한 object 타입임을 피하기 위해 아래와 같이 쓸 수 있다.
In operator narrowing
javaScript의 in 연산자로, 객체 내에 해당 값을 key로하는 프로퍼티가 있는지 확인한다. 이를 통하여 Narrowing을 할 수 있다.
type으로 객체를 정의하고, in으로 체크할 프로퍼티를 옵셔널로 남겨 두었을 경우, in 연산의 각각의 경우에서 나타날 수 있다는 것을 조심해야한다.
Instance narrowing
해당 값이 특정 클래스 혹은 생성자 함수로 만든 인스턴스 인지를 확인할 때 사용한다.
Never type과 Exhaustiveness checking
narrowing을 할 때, never type을 이용하여 모든 가능성의 조합을 체크할 수 있다.
never type은 typescript에서 존재하면 안되는 상태를 가리킨다.
💡
never 타입은 어떠한 타입이라도 할당 할 수 있지만, never이 아닌 다른 타입은 never 타입에 할당할 수 없다.
위 성질을 이용하여, switch문에서 Exhaustiveness checking을 할 수 있다.
switch 문에서 모든 경우를 처리하지 않은 경우, default 부분에서 never type에 shape을 할당하고 있으므로, error를 발생시킨다. 하지만 switch 문에서 모든 경우를 처리했다면, default 부분에서 never type에 shape를 할당하는 동작은 이루어지지않아, 에러가 발생하지 않는다.
Type predicates
특정 변수(pet)의 타입이 Fish인지 Bird 인지 확인해야한다면, type predicate를 사용함으로써, type Guard를 실현 할 수 있다.
parameterName is Type 형식으로 작성하며, parameterName은 현재 함수의 파라미터 이름이어야 한다.
Discriminated unions
Discriminated unions은 각각의 타입의 경우에 (특히 문자열 리터럴을 사용할 경우) 어떻게 동작할지 기술할 때 유용하다.
circle은 radius를 가질 것이고 square은 sideLength를 가질 것이다.
kind에 string을 쓰는 대신 "circle" | "square" 와 같은 문자열 리터럴을 쓰면 스펠링오류같은 걸 방지할 수 있다.
도형의 넓이를 구하는 함수 getArea를 만든다고 하자.
radius는 optional이기때문에 number | undefined이다. 이를 해결하기 위해 shape.kind를 사용한다고 하더라도 같은 에러가 발생한다.
circle일 경우에만 handling 했다고 하지만, TypeScript는 shape.kind‘circle’이든 ‘square’이든 radius 프로퍼티가 있다고 확신할 수 없기 때문이다.
이러한 경우에 (우리는 circle일 경우에 radius가 항상 있다는 것을 알고 있으므로, 항상 넣을 것이기 때문) typeScript에게 non-null assertions (!)을 통해 강제로 radius가 있다고 알려줄 수 있다.
위 방법은 좋지 않은 방법으로 아래와 같이 바꾸는 것이 좋다.
JavaScript 돌아가기
메인으로 돌아가기
타입스크립트에서 Narrowing을 하는 이유는, 각각의 타입을 입력받을 경우 어떻게 핸들링할 지를 정하여 예상치 못한 타입에 에러가 발생하는 것을 막기 위함이다.
동시에 type guard를 실현할 수 있는데, type guard가 무엇인지를 알아보기 위해 아래의 예를 살펴보자.
위의 문제는 type Assertion을 통해 해결할 수 있다.
이런 방법식은 코드가 지저분해지고, 가독성이 떨어지며 유지보수가 힘들게 한다. 이를 해결하기 위해 TypeScript도 해당 위치에 변수(또는 객체, 함수의 인자)가 어떤 타입을 갖고 있는지 알 필요가 있다. 이를 Type Guard 라고 한다.
Typeof operator narrowing
다양한 방법으로 Narrowing을 할 수 있고, 조심해야할 점이 있다. 이를 살펴보자.
원하는 타입으로 값이 입력되었는지 확인하기 위해, if문의 조건절 안에 typeof 연산자를 사용할 것이고, 그 결과로 아래의 값중 하나로 반환 받을 것이다.
"string"
"number"
"bigint"
"boolean"
"symbol"
"undefined"
"object"
"function"
이 방법 역시 좋은 방법이지만, 조심해야할 부점은 typeof null 의 결과 값도 object 이다. 객체 타입만( {} ) object 일 것이라 생각하지만, 배열도(typeof []) object 이다.
이를 해결하기 위해서 TypeScript 에서는 Truthiness narrowing 이라는 것을 제시했다,
Truthiness narrowing
실제로 존재하는 단어는 아니나, 익숙해지기 위해 붙인 단어이다.
JavaScript에서 if문의 조건절에서 아래의 경우를 제외하고는 모두 true로 강제된다.
0
NaN
""
0n (bigint 버전 0)
null
undefined
따라서 위의 경우에서 null 또한 object 타입임을 피하기 위해 아래와 같이 쓸 수 있다.
In operator narrowing
javaScript의 in 연산자로, 객체 내에 해당 값을 key로하는 프로퍼티가 있는지 확인한다. 이를 통하여 Narrowing을 할 수 있다.
type으로 객체를 정의하고, in으로 체크할 프로퍼티를 옵셔널로 남겨 두었을 경우, in 연산의 각각의 경우에서 나타날 수 있다는 것을 조심해야한다.
Instance narrowing
해당 값이 특정 클래스 혹은 생성자 함수로 만든 인스턴스 인지를 확인할 때 사용한다.
Never type과 Exhaustiveness checking
narrowing을 할 때, never type을 이용하여 모든 가능성의 조합을 체크할 수 있다.
never type은 typescript에서 존재하면 안되는 상태를 가리킨다.
💡
never 타입은 어떠한 타입이라도 할당 할 수 있지만, never이 아닌 다른 타입은 never 타입에 할당할 수 없다.
위 성질을 이용하여, switch문에서 Exhaustiveness checking을 할 수 있다.
switch 문에서 모든 경우를 처리하지 않은 경우, default 부분에서 never type에 shape을 할당하고 있으므로, error를 발생시킨다. 하지만 switch 문에서 모든 경우를 처리했다면, default 부분에서 never type에 shape를 할당하는 동작은 이루어지지않아, 에러가 발생하지 않는다.
Type predicates
특정 변수(pet)의 타입이 Fish인지 Bird 인지 확인해야한다면, type predicate를 사용함으로써, type Guard를 실현 할 수 있다.
parameterName is Type 형식으로 작성하며, parameterName은 현재 함수의 파라미터 이름이어야 한다.
Discriminated unions
Discriminated unions은 각각의 타입의 경우에 (특히 문자열 리터럴을 사용할 경우) 어떻게 동작할지 기술할 때 유용하다.
circle은 radius를 가질 것이고 square은 sideLength를 가질 것이다.
kind에 string을 쓰는 대신 "circle" | "square" 와 같은 문자열 리터럴을 쓰면 스펠링오류같은 걸 방지할 수 있다.
도형의 넓이를 구하는 함수 getArea를 만든다고 하자.
radius는 optional이기때문에 number | undefined이다. 이를 해결하기 위해 shape.kind를 사용한다고 하더라도 같은 에러가 발생한다.
circle일 경우에만 handling 했다고 하지만, TypeScript는 shape.kind‘circle’이든 ‘square’이든 radius 프로퍼티가 있다고 확신할 수 없기 때문이다.
이러한 경우에 (우리는 circle일 경우에 radius가 항상 있다는 것을 알고 있으므로, 항상 넣을 것이기 때문) typeScript에게 non-null assertions (!)을 통해 강제로 radius가 있다고 알려줄 수 있다.
위 방법은 좋지 않은 방법으로 아래와 같이 바꾸는 것이 좋다.
JavaScript 돌아가기
메인으로 돌아가기
타입스크립트에서 Narrowing을 하는 이유는, 각각의 타입을 입력받을 경우 어떻게 핸들링할 지를 정하여 예상치 못한 타입에 에러가 발생하는 것을 막기 위함이다.
동시에 type guard를 실현할 수 있는데, type guard가 무엇인지를 알아보기 위해 아래의 예를 살펴보자.
위의 문제는 type Assertion을 통해 해결할 수 있다.
이런 방법식은 코드가 지저분해지고, 가독성이 떨어지며 유지보수가 힘들게 한다. 이를 해결하기 위해 TypeScript도 해당 위치에 변수(또는 객체, 함수의 인자)가 어떤 타입을 갖고 있는지 알 필요가 있다. 이를 Type Guard 라고 한다.
Typeof operator narrowing
다양한 방법으로 Narrowing을 할 수 있고, 조심해야할 점이 있다. 이를 살펴보자.
원하는 타입으로 값이 입력되었는지 확인하기 위해, if문의 조건절 안에 typeof 연산자를 사용할 것이고, 그 결과로 아래의 값중 하나로 반환 받을 것이다.
"string"
"number"
"bigint"
"boolean"
"symbol"
"undefined"
"object"
"function"
이 방법 역시 좋은 방법이지만, 조심해야할 부점은 typeof null 의 결과 값도 object 이다. 객체 타입만( {} ) object 일 것이라 생각하지만, 배열도(typeof []) object 이다.
이를 해결하기 위해서 TypeScript 에서는 Truthiness narrowing 이라는 것을 제시했다,
Truthiness narrowing
실제로 존재하는 단어는 아니나, 익숙해지기 위해 붙인 단어이다.
JavaScript에서 if문의 조건절에서 아래의 경우를 제외하고는 모두 true로 강제된다.
0
NaN
""
0n (bigint 버전 0)
null
undefined
따라서 위의 경우에서 null 또한 object 타입임을 피하기 위해 아래와 같이 쓸 수 있다.
In operator narrowing
javaScript의 in 연산자로, 객체 내에 해당 값을 key로하는 프로퍼티가 있는지 확인한다. 이를 통하여 Narrowing을 할 수 있다.
type으로 객체를 정의하고, in으로 체크할 프로퍼티를 옵셔널로 남겨 두었을 경우, in 연산의 각각의 경우에서 나타날 수 있다는 것을 조심해야한다.
Instance narrowing
해당 값이 특정 클래스 혹은 생성자 함수로 만든 인스턴스 인지를 확인할 때 사용한다.
Never type과 Exhaustiveness checking
narrowing을 할 때, never type을 이용하여 모든 가능성의 조합을 체크할 수 있다.
never type은 typescript에서 존재하면 안되는 상태를 가리킨다.
💡
never 타입은 어떠한 타입이라도 할당 할 수 있지만, never이 아닌 다른 타입은 never 타입에 할당할 수 없다.
위 성질을 이용하여, switch문에서 Exhaustiveness checking을 할 수 있다.
switch 문에서 모든 경우를 처리하지 않은 경우, default 부분에서 never type에 shape을 할당하고 있으므로, error를 발생시킨다. 하지만 switch 문에서 모든 경우를 처리했다면, default 부분에서 never type에 shape를 할당하는 동작은 이루어지지않아, 에러가 발생하지 않는다.
Type predicates
특정 변수(pet)의 타입이 Fish인지 Bird 인지 확인해야한다면, type predicate를 사용함으로써, type Guard를 실현 할 수 있다.
parameterName is Type 형식으로 작성하며, parameterName은 현재 함수의 파라미터 이름이어야 한다.
Discriminated unions
Discriminated unions은 각각의 타입의 경우에 (특히 문자열 리터럴을 사용할 경우) 어떻게 동작할지 기술할 때 유용하다.
circle은 radius를 가질 것이고 square은 sideLength를 가질 것이다.
kind에 string을 쓰는 대신 "circle" | "square" 와 같은 문자열 리터럴을 쓰면 스펠링오류같은 걸 방지할 수 있다.
도형의 넓이를 구하는 함수 getArea를 만든다고 하자.
radius는 optional이기때문에 number | undefined이다. 이를 해결하기 위해 shape.kind를 사용한다고 하더라도 같은 에러가 발생한다.
circle일 경우에만 handling 했다고 하지만, TypeScript는 shape.kind‘circle’이든 ‘square’이든 radius 프로퍼티가 있다고 확신할 수 없기 때문이다.
이러한 경우에 (우리는 circle일 경우에 radius가 항상 있다는 것을 알고 있으므로, 항상 넣을 것이기 때문) typeScript에게 non-null assertions (!)을 통해 강제로 radius가 있다고 알려줄 수 있다.
위 방법은 좋지 않은 방법으로 아래와 같이 바꾸는 것이 좋다.
JavaScript 돌아가기
메인으로 돌아가기
타입스크립트에서 Narrowing을 하는 이유는, 각각의 타입을 입력받을 경우 어떻게 핸들링할 지를 정하여 예상치 못한 타입에 에러가 발생하는 것을 막기 위함이다.
동시에 type guard를 실현할 수 있는데, type guard가 무엇인지를 알아보기 위해 아래의 예를 살펴보자.
위의 문제는 type Assertion을 통해 해결할 수 있다.
이런 방법식은 코드가 지저분해지고, 가독성이 떨어지며 유지보수가 힘들게 한다. 이를 해결하기 위해 TypeScript도 해당 위치에 변수(또는 객체, 함수의 인자)가 어떤 타입을 갖고 있는지 알 필요가 있다. 이를 Type Guard 라고 한다.
Typeof operator narrowing
다양한 방법으로 Narrowing을 할 수 있고, 조심해야할 점이 있다. 이를 살펴보자.
원하는 타입으로 값이 입력되었는지 확인하기 위해, if문의 조건절 안에 typeof 연산자를 사용할 것이고, 그 결과로 아래의 값중 하나로 반환 받을 것이다.
"string"
"number"
"bigint"
"boolean"
"symbol"
"undefined"
"object"
"function"
이 방법 역시 좋은 방법이지만, 조심해야할 부점은 typeof null 의 결과 값도 object 이다. 객체 타입만( {} ) object 일 것이라 생각하지만, 배열도(typeof []) object 이다.
이를 해결하기 위해서 TypeScript 에서는 Truthiness narrowing 이라는 것을 제시했다,
Truthiness narrowing
실제로 존재하는 단어는 아니나, 익숙해지기 위해 붙인 단어이다.
JavaScript에서 if문의 조건절에서 아래의 경우를 제외하고는 모두 true로 강제된다.
0
NaN
""
0n (bigint 버전 0)
null
undefined
따라서 위의 경우에서 null 또한 object 타입임을 피하기 위해 아래와 같이 쓸 수 있다.
In operator narrowing
javaScript의 in 연산자로, 객체 내에 해당 값을 key로하는 프로퍼티가 있는지 확인한다. 이를 통하여 Narrowing을 할 수 있다.
type으로 객체를 정의하고, in으로 체크할 프로퍼티를 옵셔널로 남겨 두었을 경우, in 연산의 각각의 경우에서 나타날 수 있다는 것을 조심해야한다.
Instance narrowing
해당 값이 특정 클래스 혹은 생성자 함수로 만든 인스턴스 인지를 확인할 때 사용한다.
Never type과 Exhaustiveness checking
narrowing을 할 때, never type을 이용하여 모든 가능성의 조합을 체크할 수 있다.
never type은 typescript에서 존재하면 안되는 상태를 가리킨다.
💡
never 타입은 어떠한 타입이라도 할당 할 수 있지만, never이 아닌 다른 타입은 never 타입에 할당할 수 없다.
위 성질을 이용하여, switch문에서 Exhaustiveness checking을 할 수 있다.
switch 문에서 모든 경우를 처리하지 않은 경우, default 부분에서 never type에 shape을 할당하고 있으므로, error를 발생시킨다. 하지만 switch 문에서 모든 경우를 처리했다면, default 부분에서 never type에 shape를 할당하는 동작은 이루어지지않아, 에러가 발생하지 않는다.
Type predicates
특정 변수(pet)의 타입이 Fish인지 Bird 인지 확인해야한다면, type predicate를 사용함으로써, type Guard를 실현 할 수 있다.
parameterName is Type 형식으로 작성하며, parameterName은 현재 함수의 파라미터 이름이어야 한다.