[解決済み] タイプスクリプト。カスタムタイプに対する typeof のチェック
質問
私はカスタムタイプを持っています。
export type Fruit = "apple" | "banana" | "grape";
文字列がFruit型に含まれるかどうかを判断したいのですが、どうすればよいですか?どうすれば実現できますか?
以下はうまくいきません。
let myfruit = "pear";
if (typeof myfruit === "Fruit") {
console.log("My fruit is of type 'Fruit'");
}
どんな考えでもありがたい
どのように解決するのですか?
簡単な答えです。
を使うことはできません。
typeof
を実行時にチェックするために
interface
の型をチェックする必要があります。 その代わりに
ユーザ定義型ガード関数
を書いて、そのような型をチェックすることができます。
const fruit = ["apple", "banana", "grape"] as const;
type Fruit = (typeof fruit)[number];
const isFruit = (x: any): x is Fruit => fruit.includes(x);
let myfruit = "pear";
if (isFruit(myfruit)) {
console.log("My fruit is of type 'Fruit'");
}
長い回答が続きます。
TypeScriptにおける値と型の違いについて、特に
typeof
演算子に関するものです。 ご存知の通り、TypeScriptはJavaScriptに静的な型システムを追加しています。
がトランスパイルされると、その型システムは消去されます。
. TypeScriptの文法は、いくつかの式や文が
値
を参照するものもあれば、実行時に存在する
型
を参照する。 値
を持つ
型を持っていますが、それ自身は型ではありません。 重要なのは、コードの中には、コンパイラが値を期待し、可能であれば見つけた式を値として解釈する場所と、コンパイラが型を期待し、可能であれば見つけた式を型として解釈する場所があることです。
は
typeof
演算子は二重生活を送っています。 式は
typeof x
は常に
x
が値であることを期待しますが
typeof x
自体はコンテキストに応じて値または型になる可能性があります。
let bar = {a: 0};
let TypeofBar = typeof bar; // the value "object"
type TypeofBar = typeof bar; // the type {a: number}
行の
let TypeofBar = typeof bar;
の行は JavaScript に渡され、その中で
JavaScript の typeof 演算子
を実行時に使用して文字列を生成します。 しかし
type TypeofBar = typeof bar
; は消され、それは
TypeScript のタイプクエリ演算子
という名前の値にTypeScriptが割り当てた静的な型を調べている。
bar
.
あなたのコードで
let myfruit = "pear";
if (typeof myfruit === "Fruit") { // "string" === "Fruit" ?!
console.log("My fruit is of type 'Fruit'");
}
typeof myfruit
は値であって型ではありません。つまり、JavaScriptの
typeof
演算子であって、TypeScriptのタイプクエリ演算子ではないのです。 これは常に値
"string"
を返しますが、それは決して
Fruit
または
"Fruit"
. TypeScriptの型クエリ演算子は実行時に型システムが消去されてしまうので、実行時に結果を得ることはできない。 をあきらめる必要がある。
typeof
演算子を使うことはできない。
あなたは何を
できること
の値をチェックすることです。
myfruit
の値を確認することです。
Fruit
文字列リテラル...例えばこのように。
let myfruit = "pear";
if (myfruit === "apple" || myfruit === "banana" || myfruit === "grape") {
console.log("My fruit is of type 'Fruit'");
}
完璧でしょう? さて、冗長なコードがたくさんあるように見えるかもしれません。 ここでは、より冗長でない方法を紹介します。 まず最初に
Fruit
の型を既存のリテラル値の配列の観点から定義します。TypeScriptは値から型を推論することはできますが、型から値を生成することはできません。
const fruit = ["apple", "banana", "grape"] as const;
export type Fruit = (typeof fruit)[number];
を確認することができます。
Fruit
が手動で自分で定義したものと同じ型であることを確認します。 次に、型のテストに
ユーザー定義のタイプガード
をこのようにします。
const isFruit = (x: any): x is Fruit => fruit.includes(x);
isFruit()
は、その引数が
fruit
配列にあるかどうかを調べ、もしあれば、引数の型を
Fruit
. その動作を見てみましょう。
let myfruit = "pear";
if (isFruit(myfruit)) {
console.log("My fruit is of type 'Fruit'");
}
このタイプガードはまた、コンパイラに
if
文の中で、その
myfruit
は
Fruit
. を受け付けるだけの関数があったとしたらどうでしょう?
Fruit
を受け付ける関数があり、その値が
Fruit
:
declare function acceptFruit(f: Fruit): void;
const myfruit = Math.random() < 0.5 ? "pear" : "banana";
関数を直接呼び出すことはできません。
acceptFruit(myfruit); // error, myfruit might be "pear"
しかし、あなたは できる をチェックした後に "then"節の内部で呼び出すことができます。
if (isFruit(myfruit)) {
acceptFruit(myfruit); // okay, myfruit is known to be "banana"
}
これが、そもそもカスタムタイプに対してチェックを行いたい理由だと思われます。 というわけで、これでできるようになりました。
要約すると
typeof
. 文字列との比較はできる。 型推論と型ガードで重複したコードを排除し、コンパイラからコントロールフローの型解析を受けることができます。
関連
-
[解決済み] オブジェクトの種類を決定しますか?
-
[解決済み] JavaScriptで値がオブジェクトであるかどうかを確認する
-
[解決済み] 型チェック:typeof、GetType、is?
-
[解決済み] Pythonで型をチェックする標準的な方法は何ですか?
-
[解決済み] TypeScriptで文字列を数値に変換する方法とは?
-
[解決済み】TypeScriptのインターフェースと型について
-
[解決済み】type()とisinstance()の違いは何ですか?)
-
[解決済み】Typescript Type 'string' はタイプに割り当てられない。
-
[解決済み] describe'という名前が見つかりません。テストランナー用の型定義をインストールする必要がありますか?
-
[解決済み] tsconfig.jsonのtargetは何のためにあるのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Typescript はタプル/配列の値からユニオン型を導出します。
-
[解決済み] TypeScriptで Object.keys return string[].
-
[解決済み] describe'という名前が見つかりません。テストランナー用の型定義をインストールする必要がありますか?
-
[解決済み] ts ES5/ES3の非同期関数やメソッドには、「Promise」コンストラクタが必要です。
-
[解決済み] ユニオン型からインターセクション型への変換
-
[解決済み] 文字列ユニオンから文字列配列へ
-
[解決済み] tsconfig.jsonのtargetは何のためにあるのですか?
-
[解決済み] TypeScriptでObject.keysがkeyof型を返さないのはなぜですか?
-
[解決済み] タイプスクリプトのパイプ(|)の意味とは?
-
[解決済み] TypeScript "this" scoping issue when called in jquery callback.