판별자로서의 Typescript 템플릿 문자열 유형

Typescript 4.5로 향상된 템플릿 리터럴 유형

TS에서 "협착"이란 무엇입니까?

Typescript 4.5 이상에서 리터럴 유형의 개선 사항을 살펴보기 전에 이 컨텍스트에서 "좁히기"가 실제로 의미하는 바를 간단히 요약하고 싶습니다. 기본적으로 엔터티의 속성을 확인하여 Typescript에서 유형의 범위를 좁힐 수 있습니다. 특정 유형에만 사용할 수 있는 속성이 엔터티에 있는 경우 Typescript는 이를 이해하고 올바른 유형을 제공할 수 있습니다.

다음 코드 예제는 이것이 의미하는 바를 보여줍니다.

type Addition = {
    sum: number;
}

type Subtraction = {
    result: number;
}

function calculate(action: Addition | Subtraction) {
    if ('sum' in action) {
      // Simple example of using properties
      // of an entity to narrow down its
      // actual type.
      //
      // 'action' is at this point of type
      // 'Addition'. Nice!
      const addition = action;
    }
}

템플릿 문자열 유형 좁히기

Typescript 버전 4.5부터 이 패턴은 백틱이 있는 특수 문자열이라고도 하는 템플릿 리터럴 유형에도 적용할 수 있습니다. 패턴 매칭은 언어에서 정말 강력해지고 있습니다.

물론 축소가 사용 가능하려면 비교의 모든 유형이 동일한 속성 키를 공유해야 합니다. 그렇지 않으면 위와 같이 공통 축소를 간단하게 사용할 수 있습니다.

다음 코드 예제에서는 템플릿 문자열이 축소를 사용하는 방법을 보여줍니다.

type Addition = {
    variant: `${string}-addition`;
    sum: number;
}

type Subtraction = {
    variant: `${string}-subtraction`;
    result: number;
}

function process(action: Addition | Subtraction) {
    if (action.variant === "simple-addition") {
        // Stupid simple example, but you get the idea:
        // We used 'simple-addition', and the pattern 
        // matching by TS understood that '...-addition'
        // can be discriminated to 'Addition'.
        const addition = action;
    }
}
//
// Example that DOES NOT work.
//
// This demo illustrates that the
// discriminante has to be a string,
// else the pattern matching worn't work.

type Addition = {
    variant: `${string}-arithemtic`;
    sum: number;
}

type Subtraction = {
    variant: `${number}-arithemtic`;
    result: number;
}

function process(action: Addition | Subtraction) {
    if (action.variant === "123-arithemtic") {
        // Still 'Addion | Subtraction',
        // as we can only compare against
        // a string '123-arithmetic', which
        // is of course the same for both.
        const addition = action;
    }
}

이제 Typescript에서 템플릿 리터럴의 범위를 좁히는 방법을 알게 되었습니다! 이것은 자주 사용하지 않을 기능일 수 있지만 적절할 때 기능이 없는 것보다 코드 복잡성을 크게 줄이고 코드베이스를 조금 더 깔끔하게 유지할 수 있다고 생각합니다.