タイプスクリプトにおけるより安全な述語


タイプスクリプトには、型述語と呼ばれる機能があります.
しかし、この機能は100 %安全です.
そこで、本稿では述語タイプを使用するより安全な方法を紹介したいと思います👶

概要


タイプスクリプトの述語に関する問題の1つは、タイプアサーションロジックが正しいかどうか気にしないことです.
実際には、関数が適切に型を決定できない場合でも、関数が文法的に正しい限り、コンパイラはエラーを与えません.
したがって、型述語を使用するとき、我々はこのようにしなければなりませんあなたのタイプアサーション論理を通して決定目標をタイプt👶
//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
}
以下では、タイプスクリプトの中でどのような述語が似ているかを説明します.そして、問題がどのようにそれを解決するかについて見てください.

述語とは?


コンピュータサイエンスの文脈において、「述語」という言葉は、広義で「何かが真実であるか間違っているかを決定する機能」を意味する👶
以下のリンクは分かりやすいです.
https://stackoverflow.com/questions/3230944/what-does-predicate-mean-in-the-context-of-computer-science
したがって、「型述語」とは、「型を決定する関数」を意味する.
そのような機能は、typescriptだけでなく、Lispなどの他の言語でも実装されます.
タイプスクリプトの文脈で型述語を言うとき、それは特に以下の機能を意味します
//type predicate in TypeScript
function isFish(pet: Fish | Bird): pet is Fish {
  return (pet as Fish).swim !== undefined;
}
ここでわかるように、型のアサート関数の戻り値の型をBooleanからX is Tに変更することで簡単に型述語を書くことができます.
型述語は、次のように変数の型を絞り込みます(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";
}
これは本当に簡単な例ですが、複雑なコードでこの種の間違いを見落とすことができます.

タイプ述語を安全に書くには?


それで、我々は正確に何をしなければなりませんか?ここでは,本稿の初めの結論を再度説明した.
あなたのタイプアサーション論理を通して決定目標をタイプt👶.
これを行うには多くの方法がありますが、今のところ三項演算子は便利です.
//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
}
安全なタイプの生命はあなたと共にありますように👶