この投稿シリーズの前の部分では、安全な null 可能性について説明しました。
ここで、TypeScript のデフォルト動作の 3 番目で最後の問題、 動的型付けの残り.
を説明し、解決します。次の内容を取り上げます:
TypeScript は、型付けが非常に動的である JavaScript とは対照的に、「静的型チェッカー」であると想定されています。
ただし、この投稿シリーズの前の部分では、TypeScript が JavaScript のスーパーセットとして構築されていることも説明しました。
問題は次のとおりです。JavaScript 動的型付けシステムの一部が TypeScript に残っています。したがって、これらの残りの動作を抑制して完全な静的型付けを実現する方法を説明します。
問題の最良の例は等価性チェックです。 JavaScript では、== は正確には等価性チェックではなく、等価性チェック:
です。
1 == "1"; // true
型が異なっていても、JavaScript が値を比較できるように、いくつかの変換ルールが機能します。ルールの詳細は覚えるのが難しく、非常に奇妙な場合があり、すべての動的言語 (たとえば PHP など) でまったく同じではないため、多くのエラーが発生する可能性があります。
これらの等価性チェックは、JavaScript のような動的に型付けされた言語でのみ意味を持ちます。 TypeScript で作業すると決めた瞬間から、実際の等価性チェック (型と値) のみを使用する必要があります。
1 === "1"; // false
eqeqeq lint ルールによって強制されます。
Java、C#、Rust などの言語を使用している人は、この問題に特に注意する必要があります。JavaScript や TypeScript の == は、これらの言語の == と同じ意味ではないからです。 JavaScript と TypeScript では、同じ動作を実現するには 3 番目の = が必要です。
今の状況は安全だと思いますか?残念ながら、変換は暗黙的に行われる可能性があるため、そうではありません:
let tax: number | undefined = 0; if (tax) { console.log("Process payment"); } if (!tax) { throw new Error(); }
上の例は次と同等です:
let tax: number | undefined = 0; if (tax == true) { console.log("Process payment"); } if (tax == false) { throw new Error(); }
ご覧のとおり、暗黙的な == があったため、変換は依然として発生します。0 は true と同等ではなく、false と同等です。そのため、税金が有効な値であるにもかかわらずエラーが発生します。
strict-boolean-expressions lint ルールは、そのような暗黙の条件を禁止し、実際のチェックを強制します:
let tax: number | undefined = 0; if (tax !== undefined) { console.log("Process payment"); } if (tax === undefined) { throw new Error(); }
これは、JavaScript でのクイック条件に慣れている人にとっては従うのが最も面倒なルールの 1 つかもしれませんが、大局的に考えると、これは Java、C#、Rust などの他の言語で物事を行う通常の方法にすぎません。
設定部分に示されているように、すべてのエラーを回避するには、allowNumber サブオプションとallowString サブオプションを無効にすることが重要です。
許可される唯一の例外は、オブジェクトと配列です。これらのケースは、文字列や数値とは異なり、偽の値を持たないため安全です。したがって、次のようにしても問題ありません:
let movie: Movie | undefined; if (movie) {} if (!movie) {}
注: switch ステートメントは内部で === を使用しているため、すでに安全です。
strict-boolean-expressions lint ルールは、条件チェックがタイプ セーフであるように注意しますが、if 以外の条件構文もあります:
const movieRating = userRating || 5; // Which is a shorter version of: const movieRating = userRating == true ? userRating : 5;
ユーザーが 0 と評価した場合、0 は false に相当するため、評価は 0 ではなく 5 になります。
最新の JavaScript を使用すると回避できます:
const movieRating = userRating ?? 5; // Which is a shorter version of: const movieRating = userRating !== undefined && userRating !== null ? userRating : 5;
これは、prefer-nullish-coalescing lint ルールによって強制できます。
ご了承ください ?? || どこでも使用すべきではありません: ||ブール値を使用する場合も、
は有効です。JavaScript では、演算子は数値の数学的加算と文字列の連結の両方に使用できます。エラーになります。
"There is " 3 1 "Matrix movies"; // 31 "There is " (3 1) "Matrix movies"; // 4
演算子は数学的な加算のために予約されている必要があります。少なくとも、これは、restrict-plus-operands lint ルールが適用する同じ型のデータでのみ使用する必要があります。
最新の JavaScript のテンプレート文字列は、prefer-template lint ルールによって強制される文字列の連結に使用する必要があります。
const movie = `Everything everywhere all at once`; `${movie} is the best movie!`;
逆に、テンプレート文字列では文字列のみを使用する必要があり、これは、restrict-template-expressions lint ルールによって適用されます。
型の混合が実際に必要な場合は、変換を明示的に行う必要があります:
const total = 3; `There is ${total.toFixed()} Matrix movies`;
テンプレート文字列はネストできることに注意してください:
const total = 3; `There is ${total.toFixed()} Matrix movie${total > 1 ? "s" : ""}`;
このシリーズの投稿はこれで終わりです。私のアカウント (このページの右上にあるボタン) をフォローすると、TypeScript や Angular などの他のトピックに関する他の投稿がいつ公開されるかを知ることができます。
私に連絡したいですか?手順は概要にあります。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3