TypeScript의 더 안전한 유형 술어

3955 단어 programmingtypescript
TypeScript에는 type predicate라는 기능이 있습니다.
그러나 이 함수는 100% 형식 안전하지 않습니다.
그래서 이 글에서 타입 술어를 사용하는 더 안전한 방법을 소개하려고 합니다👶

요약



TypeScript의 유형 술어에 대한 문제 중 하나는 유형 어설션 논리가 올바른지 상관하지 않는다는 것입니다.
실제로 함수가 유형을 제대로 결정할 수 없더라도 함수가 문법적으로 올바른 한 컴파일러는 오류를 제공하지 않습니다.

따라서 유형 술어를 사용할 때는 이런 방식을 취해야 합니다. type assertion logic👶을 통해 T|null 유형의 변수에 결정 대상을 할당합니다.

//safer type predicate
function isTypeA(x: typeA | typeB): x is TypeA {
    const maybeTypeA: typeA | null =
        if ([logic which is true only when x is TypeA]) ? x : null
    return !!maybeTypeA
}


다음에서는 TypeScript에서 유형 술어가 어떤 것인지 설명합니다. 그런 다음 문제와 위의 코드가 문제를 해결하는 방법을 확인하십시오.

유형 술어란 무엇입니까?



컴퓨터 과학의 맥락에서 "술어"라는 단어는 넓은 의미에서 "어떤 것이 참인지 거짓인지를 결정하는 기능"을 의미합니다👶
다음 링크는 이해하기 쉽습니다.
https://stackoverflow.com/questions/3230944/what-does-predicate-mean-in-the-context-of-computer-science

따라서 "유형 술어"는 "유형을 결정하는 함수"를 의미한다고 할 수 있습니다.
이러한 기능은 TypeScript뿐만 아니라 LISP와 같은 다른 언어에서도 구현됩니다.

TypeScript 컨텍스트에서 유형 술어를 말할 때 특히 다음 함수( official documentation )를 의미하는 것이 중요합니다.

//type predicate in TypeScript
function isFish(pet: Fish | Bird): pet is Fish {
  return (pet as Fish).swim !== undefined;
}


여기에서 볼 수 있듯이 유형 어설션 함수의 반환 값 유형을 부울에서 X is T 로 변경하여 유형 술어를 쉽게 작성할 수 있습니다.

그리고 type 술어는 다음과 같이 변수의 유형을 좁힙니다(from official documentation ).

//Example usage of type predicate in TypeScript
let pet = getSmallPet();

if (isFish(pet)) {
  pet.swim();
} else {
  pet.fly();
}


유형 술어는 typeofinstanceof가 수행할 수 없는 유형 어설션을 수행할 수 있습니다.

유형 술어는 언제 안전하지 않습니까?



형식 술어는 유용하지만 형식을 결정하는 논리가 올바르지 않으면 안전하지 않습니다.
다음 예제는 분명히 올바르지 않지만 컴파일러에서 무시됩니다.

//Example of unsafe type predicate in TypeScript
function isNumber(x: unknown): x is Number {
  return typeof x === "boolean";
}


이것은 정말 간단한 예이지만 복잡한 코드에서 이런 종류의 실수를 간과하거나 할 수 있습니다.

유형 술어를 어떻게 안전하게 작성할 수 있습니까?



그렇다면 정확히 무엇을 해야 할까요? 여기서 이 글의 서두에서 내린 결론을 다시 설명한다.

type assertion logic👶을 통해 결정 대상을 T|null 유형의 변수에 할당하는 것이 가장 중요합니다.
이를 수행하는 방법은 여러 가지가 있지만 현재로서는 삼항 연산자가 편리합니다.

//safer type predicate
function isTypeA(x: unknown): x is TypeA {
    const maybeTypeA: typeA | null =
        if ([logic which is true only when x is TypeA]) ? x : null
    return !!maybeTypeA
}


논리가 올바르지 않더라도 유형 술어가 컴파일러에 의해 올바른 것으로 보이는 것이 문제라는 점을 기억하십시오.
따라서 위의 방법을 취하면 잘못된 논리에 의해 not-TypeA 인수가 TypeA로 결정되면 변수 'maybeTypeA'는 삼항 연산자에 의해 null이 되고 결과는 false로 결정됩니다.

다음과 같이 일반적인 것과 비교하면 그 차이가 분명합니다.

// In the typical way, if the condition is wrong, the type predicate will also return the wrong result.
function isTypeA(x: unknown): x is TypeA {
    return if ([logic which is true only when x is TypeA]).
}

// In this way of writing, if the condition is wrong, type predicate can detect it (i.e. it can return false).
function isTypeA(x: unknown): x is TypeA {
    const maybeTypeA: typeA | null =
        if ([logic which is true only when x is TypeA]) ? x : null
    return !!maybeTypeA
}


안전한 타입 라이프가 함께 하길👶

좋은 웹페이지 즐겨찾기