본문으로 바로가기

Type assertions (타입 단언)

category Programming Language/🟦 Typescript 2020. 10. 21. 05:08

타입 어설션에는 두 가지 형식이 있습니다.

 

하나는 angle-bracket(<>)구문, 다른 하나는 다른 하나는 as 구문입니다. 

역할은 동일합니다. React를 사용한다면 <> 구문으로 type assertions하는 것은 불가능합니다. jsx와 겹치기 때문이죠.

 

저는 그냥 as를 사용하는 걸로 했습니다. 애초에 <> 구문을 넣으면 Generic과 헷갈려서요.

// <> 구문
let str: any = "this is a string";
let strLength: number = (<string>someValue).length;

console.log(strLength);

// as 구문
let secStr: any = "this is a string";
let secStrLength: number = (someValue as string).length;

console.log(secStrLength);

 

타입 어설션은 컴파일러가 가진 정보를 무시하고 프로그래머가 원하는 임의의 타입을 값에 할당하고자 할 때 사용합니다.  별도의 선언이 없어도 추론이 잘 되는 경우에는 타입 선언을 하지 않고, 그렇지 않은 경우에만 선언하는 것이 편리하고 자연습니다.

 

타입 단언이 필요한 부분을 들어보겠습니다.

const div = document.querySelector("div");
div.innerHTML = "asdf";

일반 js에서는 문제가 없는 코드지만 ts에서는 div가 null이 가능성이 있으므로 inneHTML 을 사용할 수 없게 합니다.

이 경우 div가 HTMLDivElement임을 단언하면 innnerHTLM 을 사용할 수 있게 됩니다.

const div = document.querySelector("div") as HTMLDivElement;
div.innerHTML = "asdf";

 

 

조금 더 복잡한 예시를 들어보겠습니다.

class Job {
  private _job;
  constructor(_job: string) {
    this._job = _job;
  }

  quit() {
    console.log("I'm done");
  }

  isDoctor(): boolean {
    return this._job === "doctor" ? true : false;
  }

  isKiller(): boolean {
    return this._job === "killer" ? true : false;
  }
}

class Doctor extends Job {
  constructor(_job: string) {
    super(_job);
  }
  heal() {
    console.log("heal!");
  }
}

class Killer extends Job {
  constructor(_job: string) {
    super(_job);
  }
  kill() {
    console.log("kill!");
  }
}

function doYourJob(man: Job) {
  if (man.isDoctor()) {
    man.heal(); // Property 'heal' does not exist on type 'Job'.
  } else if (man.isKiller()) {
    man.kill(); // Property 'kill' does not exist on type 'Job'.
  } else {
    man.quit();
  }
}

 

man 파라미터는 Job 클래스의 인스턴스이지만 Job 클래스는 heal과 kill이란 메서드를 가지고 있지 않기 때문에 해당 코드는 컴파일 되지 않습니다.

 

그러나 코드를 작성한 코더는 위 man이 doctor이거나 killer이거나 혹은 아무 것도 아닌 것을 알 수 있습니다. 이럴 경우 아래와 같이 <> 혹은 as를 활용해 타입 어설션을 할 수 있습니다.

function doYourJob(man: Job) {
  if (man.isDoctor()) {
    (<Doctor>man).heal();
  } else if (man.isKiller()) {
    (man as Killer).kill();
  } else {
    man.quit();
  }
}

const me = new Doctor("doctor");
doYourJob(me);

 


darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체