함수에 Union을 사용하면...
function 더하기(x: number | string) {
// return x + 1; 에러 발생
}
x는 숫자 또는 문자이기 때문에 +1을 해도 분명 코드상 문제가 없지만 에러를 발생시킨다.
TypeScript는 number 타입 또는 string 타입만 + 연산이 가능한데, 현재 x는 number | string 타입이기 때문에
+ 연산이 불가능하여서 에러가 발생한다.
즉, 아직 파라미터의 타입이 확실하지 않기 때문에 파라미터 조작 시 에러가 발생하는 것이다.
function 함수(x? :number) :number {
// return x + 1 에러 발생
}
또 이런 코드도 타입스크립트에서는 에러가 발생한다.
x의 타입이 number 혹은 undefined 이기 때문에 만약에 undefined라면 + 1 연산이 불가능하기 때문에 발생한 것이다.
두 상황 모두 타입을 확정시켜야 에러가 나지 않는다.
TypeScript에서 확정 시키는 방법은 2가지가 있는데,
1. 타입을 Narrowing을 해서 하나로 정한다.
2. Assert 를 사용해서 타입을 정한다.
Type Narrowing
특별한 함수나 기능이 있는게 아닌 if문 등으로 타입을 하나로 정해주는 방법을 말한다.
function 더하기(x :number | string){
if (typeof x === 'number') {
return x + 1
}
else if (typeof x === 'string') {
return x + 1
}
else {
return 0
}
}
if문과 typeof 키워드를 사용해 현재 파라미터의 타입을 검사해서
" string " 일때와 " number " 일때를 나눠서 코드를 짜야 정상적으로 사용이 가능하다.
타입스크립트는 타입이 확실하지 않을 때 생기는 부작용을 막기위한 장치이기 때문에 확정적으로 사용해야한다.
근데 함수 안에서 if문을 쓸 때 마지막에 else {} 가 없다면 에러가 난다.
return을 하지 않는 조건문이 있다면 나중에 버그가 생길 수 있어 에러를 발생시크는 것인데,
tsconfig.js 파일에 "noImplicitReturns" : false, 옵션을 준다면 발생하지 않는다.
=> 하지만 현재 else {} 문이 없어도 함수에 자동으로 number | string | undefined , undefined 타입이 추가되어
없어도 에러가 발생 안한다.
Narrowing을 할 때 꼭 typeof를 사용할 필요는 없고 타입을 확정할 수 있는 코드라면 어떤 것도 Narrowing 역할이
가능하다.
ex) in, instanceof 키워드 등..
Type Assertion
Narrowing 하는 방법 외에 간단하게 assert를 사용할 수 있다.
" 변수의 타입을 특정 유형으로 생각해라 " 라는 뜻으로 사용하면 타입스크립트가 넘어간다.
변수명 as 타입
방식으로 as라는 키워드를 사용하면 된다.
function 더하기(x :number | string){
return (x as number) + 1
}
console.log( 더하기(123) )
x as number 라고 쓴다면
" x 는 number 유형의 변수이다 " 라는 뜻으로, 타입이 변경된다.
함수에 무조건 특정 유형이 올 경우에만 사용해야 안전하게 쓸 수 있다.
as 키워드의 특징이 있는데,
1. as 키워드는 Union 타입 같은 복잡한 타입을 하나의 정확한 타입으로 줄이는 역할을 수행한다.
let num: number = 10;
// num as string; 에러 발생
number 타입에게 as string을 사용해서 바꾸면 에러가 발생한다.
2. 코드 실행 결과는 as가 있을 때나 없을 때나 동일하다.
function 더하기(x :number | string){
return (x as number) + 1
}
console.log( 더하기("123") )
숫자 123이 아닌 문자 "123"을 넣은 경우 as number로 숫자 타입으로 인식하게 만들었지만
return 되는 결과는 "1231" 출력된다.
즉, 타입스크립트가 인식을 할 수 있게 해주는 거지 실제로 바뀌는 것은 아니다.
Assert는 분명 간편하게 사용할 수 있지만, 난발하게 되면 타입스크립트의 주 기능인 타입 체크를 안쓰겠다는 뜻이
되어버린다.
그래서 Assert는 특정 상황에 주로 사용하는데,
1. 타입 에러가 발생하는데 어디서 발생하는지 모르겠어서 임시로 에러 해결용으로 사용한다.
2. 어떤 타입이 들어올지 정확하게 알 고 있는 경우에 컴파일 에러가 코드 실행을 방해할때 사용한다.
그 외에 상황은 왠만하면 Type Narrowiung을 사용하는 것이 더 정확하게 코드를 작성할 수 있다.
'TypeScript > 기초' 카테고리의 다른 글
[TypeScript] Literal Type (2) | 2022.05.25 |
---|---|
[TypeScript] type 키워드 & readonly (1) | 2022.05.10 |
[TypeScript] 함수에 타입 지정하기 (1) | 2022.05.08 |
[TypeScript] 추가 타입 (5) | 2022.04.21 |
[TypeScript] 기본 타입 정리 (0) | 2022.04.16 |