타입 확정하기 Narrowing & Assertion

|

코딩애플강의를 보고 정리했습니다.

function 내함수(x: number | string) {
  return x + 1; //에러남
}

이렇게 작성을 해주면 이런 에러가난다.
Operator '+' cannot be applied to types 'string | number' and 'number'

string | number 같은 union type 에는 일반적으로 조작을 못하게 막아놔서 그런건데 이럴 경우
(간단하게 파라미터로 들어오는 x의 값이 문자일지 숫자일지 모르기때문임)

  1. 타입을 하나로 Narrowing(축소)해주거나,
  2. Assert(주장)해주거나

둘 중 하나를 해주면 된다.

Type Narrowing

if문등으로 타입을 하나로 정해주는것을 뜻한다.
다른말로 defensive하게 코딩한다 라고도 한다.

Ex)

function 내함수(x: number | string) {
  if (typeof x === 'number') {
    return x + 1;
  } else if (typeof x === 'string') {
    return x + 1;
  } else {
    return 0;
  }
}

Narrowing타입 방식에는 몇가지 알아둬야할게있다.

  • 마지막에 else{} 없으면 에러남
    (return 하지 않는 조건문이 있다면 나중에 버그가 생길 수 있어서 에러를 내줌)

  • 꼭 typeof를 쓸 필요는 없고 타입을 하나로 확정지을 수 있는 코드라면 어떤것도 Narrowing역할을 해줄 수 있다.
    (in,instanceof 등)

Type Assertion

변수명 as number

function 내함수(x :number | string){
    // 이 변수를 number라고 주장하겠다는 뜻임 하지만,
    // 이러려면 내가 함수에 무조건 숫자가 들어올 것이다 라는 사실을 알고있어야 안전하게 쓰임
    return (x as number) + 1
}
console.log( 내함수(123) );

as 키워드에는 사용시 특징이있다.

  1. as 키워드는 유니온 타입 같은 복잡한 타입을 하나의 정확한 타입으로 줄이는 역할을 수행함
    EX) (number 타입을 as string 이렇게 바꾸면 에러가난다)

  2. 타입실드 임시 해제용이다. 실제 코드 실행결과는 as있을 때나 없을 때나 거의 동일함

as를 쓰면 간편하지만 엄격한 타입체크 기능을 잠깐 안쓰겠다는 것과 동일하기때문에 다음과 같은 상황에서만 되도록이면 as를 쓰자.

  1. 왜 타입에러가 나는지 모르겠는 상황에 임시로 에러해결용으로 사용
  2. 내가 어떤 타입이 들어올지 정말 확실하게 알고 있는데 컴파일러 에러가 방해할 때

구식 assertion 문법

as 키워드 대신 <> 괄호를 사용했었다.
하지만 리액트에서 사용시 html태그와 헷갈릴 수 있어서 지금은 as키워드를 주로 사용한다.

let 이름 :number = 123;

(이름 as string) + 1;  //현재문법
<string>이름 + 1;   //옛날문법