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
문법만 허용됩니다.