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