Skip to content

TypeScript:asserts

TypeScript의 asserts문법에 대한 내용.

Intro

예상치 못한 일이 발생하면 오류를 throw하는 기능 세트가 있습니다. "assertion" 기능이라고 합니다.

예를 들어 Node.js에는 이를 위한 assert라는 함수가 있습니다.

예를 들면:

function multiply(x, y) {
  assert(typeof x === "number");
  assert(typeof y === "number");
  return x * y;
}

불행히도 TypeScript에서는 이러한 검사를 제대로 인코딩할 수 없습니다.

  • 느슨하게 형식화된 코드의 경우 TypeScript가 검사를 덜 수행하고,
  • 약간 보수적인 코드의 경우 사용자가 형식 어설션을 사용하도록 강제하는 경우가 많았습니다.

대안은 대신 언어가 분석할 수 있도록 코드를 다시 작성하는 것이지만 이것은 편리하지 않습니다:

function yell(str) {
  if (typeof str !== "string") {
    throw new TypeError("str should have been a string.");
  }
  // Error caught!
  return str.toUppercase();
}

궁극적으로 TypeScript의 목표는 기존 JavaScript 구문을 최소한의 방해 방식으로 입력하는 것입니다. 이러한 이유로 TypeScript 3.7에는 이러한 주장 기능을 모델링하는 "어설션 서명"이라는 새로운 개념이 도입되었습니다.

첫 번째 유형의 주장 서명은 노드의 assert기능이 작동하는 방식을 모델링합니다. 검사 중인 조건이 포함하는 범위의 나머지 부분에 대해 참이어야 함을 보장합니다.

function assert(condition: any, msg?: string): asserts condition {
  if (!condition) {
    throw new AssertionError(msg);
  }
}

다른 유형의 어설션 서명은 조건을 확인하지 않고 대신 TypeScript에 특정 변수나 속성의 유형이 다르다고 알려줍니다.

function assertIsString(val: any): asserts val is string {
  if (typeof val !== "string") {
    throw new AssertionError("Not a string!");
  }
}

제네릭에 대해서도 표현이 가능하다:

function assertIsDefined<T>(val: T): asserts val is NonNullable<T> {
  if (val === undefined || val === null) {
    throw new AssertionError(
      `Expected 'val' to be defined, but received ${val}`
    );
  }
}

IntelliJ 타입 힌트 제약

참고로 이 방법으로 IntelliJ계열 IDE의 타입 힌트를 제약할 수 있다.

Teyp Assertion

IntelliJ타입 힌트 제약은 타입 어설션을 사용한 방법도 있다.

Angle bracket

앵글 브라켓(angle-bracket)은 <>로 감싼 타입니다.

let assertion:any = "타입 어설션은 '타입을 단언'합니다.";

// 방법 1: assertion 변수의 타입을 string으로 단언 처리
let assertion_count:number = (<string>assertion).length;

as 문법

let assertion:any = "타입 어설션은 '타입을 단언'합니다.";

// 방법 2: assertion 변수의 타입을 string으로 단언 처리
let assertion_count:number = (assertion as string).length;

JSX 제약

위의 두 방법 모두 결과는 동일합니다. 하지만 JSX와 함께 사용하는 경우에는 as 문법만 허용됩니다.

See also

Favorite site