型に呼び出し署名がない式を呼び出すことができない
質問
私はリンゴと梨を持っていますが、どちらにも
isDecayed
属性があります。
interface Apple {
color: string;
isDecayed: boolean;
}
interface Pear {
weight: number;
isDecayed: boolean;
}
そして、どちらのタイプも私のフルーツバスケットに(複数回)入れることができます。
interface FruitBasket {
apples: Apple[];
pears: Pear[];
}
とりあえずバスケットが空だとします。
const fruitBasket: FruitBasket = { apples: [], pears: [] };
ここで、カゴからランダムに1種類を取り出します。
const key: keyof FruitBasket = Math.random() > 0.5 ? 'apples': 'pears';
const fruits = fruitBasket[key];
そしてもちろん、腐った果物は誰も好きではありませんから、新鮮なものだけを選びます。
const freshFruits = fruits.filter((fruit) => !fruit.isDecayed);
残念ながらTypescriptが教えてくれました。
呼び出しシグネチャを持たない型を持つ式は呼び出すことができません。型 '((callbackfn: (value: Apple, index: number, array: Apple[]) => any, thisArg?: any) => Apple[]). | ...'は互換性のあるコールサインを持ちません。
Typescriptが新鮮な果物を好まないだけなのか、それともTypescriptのバグなのでしょうか?
自分で試すことができるのは、公式の Typescript Repl .
どのように解決するのですか?
TypeScriptは構造的な型付け(ダック型付けとも呼ばれる)をサポートしており、つまり
型が同じメンバを共有している場合、互換性があります。
. あなたの問題点は
Apple
と
Pear
はすべてのメンバーを共有していないため、互換性がありません。しかし、この型は
isDecayed: boolean
のメンバーだけを持つ別の型とは互換性があります。構造的な型付けがあるので
Apple
と
Pear
のようなインターフェイスから
このような互換性のある型を割り当てるには、さまざまな方法があります。
変数宣言時に型を割り当てる
この文は暗黙のうちに型付けされ
Apple[] | Pear[]
:
const fruits = fruitBasket[key];
変数宣言で互換性のある型を明示的に使用すればよい。
const fruits: { isDecayed: boolean }[] = fruitBasket[key];
さらに再利用性を高めるために、最初に型を定義し、それを宣言で使用することもできます(ただし、この場合
Apple
と
Pear
のインターフェースは変更する必要はありません)。
type Fruit = { isDecayed: boolean };
const fruits: Fruit[] = fruitBasket[key];
操作のために互換性のある型にキャストする
与えられた解決策の問題点は、この方法では
fruits
変数の型を変えてしまうことです。これはあなたが望むことではないのかもしれません。これを避けるには、操作の前に配列を互換性のある型に絞り込んでから、その型を
fruits
:
const fruits: fruitBasket[key];
const freshFruits = (fruits as { isDecayed: boolean }[]).filter(fruit => !fruit.isDecayed) as typeof fruits;
あるいは、再利用可能な
Fruit
という型を使うこともできます。
type Fruit = { isDecayed: boolean };
const fruits: fruitBasket[key];
const freshFruits = (fruits as Fruit[]).filter(fruit => !fruit.isDecayed) as typeof fruits;
この解決策の利点は、両方とも
fruits
と
freshFruits
は、タイプ
Apple[] | Pear[]
.
関連
-
[解決済み] エラー 型に呼び出し署名がない式は呼び出せない
-
[解決済み] 上級者向けJavaScript。この関数はなぜ括弧でくくられるのですか?重複
-
[解決済み] jqueryでdivの要素がオーバーフローしていないかチェックする
-
[解決済み] なぜJavaScriptでは!{}[true]がtrueに評価されるのですか?
-
[解決済み] bootstrap のポップオーバーがすべての要素の上に表示されない
-
[解決済み] JavaScriptで、ある文字列が別の文字列の中に出現するすべてのインデックスを見つけるにはどうすればよいですか?
-
[解決済み] TypeScriptのdeclare classとinterfaceの違いとは?
-
[解決済み] javascriptで文字列から関数を作成する方法はありますか?
-
[解決済み] JavaScriptとLuaの微妙な違い [終了しました]
-
[解決済み] JavaScriptの文字列プリミティブとStringオブジェクトの違いは何ですか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] JavaScriptを使用してHTML要素に属性を追加/更新するには?
-
[解決済み] 文字列がhtmlであるかどうかをチェックする
-
[解決済み] Javascript / jQueryでAndroid端末を検出する。
-
[解決済み] Javascriptで動的に命名されたメソッドを呼び出すにはどうすればよいですか?
-
[解決済み] react-routerのハッシュフラグメントからクエリパラメータを取得する
-
[解決済み] BlobからArrayBufferへ移行する方法
-
[解決済み] 各オブジェクトに?重複
-
[解決済み] CORS: 認証モードは 'include' です。
-
[解決済み] javascriptのキャンバスで画像をリサイズする (スムーズ)
-
[解決済み] 変異を伴わないオブジェクトからの値の削除