1. ホーム
  2. typescript

[解決済み] TypeScriptのInterface Function Property。何が違うの?

2022-03-08 10:17:19

質問

このコードで、InterfaceA型の定数への代入はうまくいくのに、InterfaceB型の定数への代入はなぜエラーを投げるのか、どなたか説明してください。

interface InterfaceA {
  doSomething (data: object): boolean;
}

interface InterfaceB {
  doSomething: (data: object) => boolean;
}

function doIt (data: { type: string; }): boolean {
    return true;
}

const A: InterfaceA = {
    doSomething: doIt
};
const B: InterfaceB = {
    doSomething: doIt
};


オンラインデモはこちら http://www.typescriptlang.org/play/index.html? ssl=19&ssc=1&pln=1& pc=1#code/JYOwLgpgTgZghgYwgAgJLmvJBBZBvAWAChlkATAewGUKBbCMAC1AHNkAKMuMOALmQoAjAFYQEYAJT9BFCgBsIcEAG5iAX2LFQkWIhTodWCACF8xUpRr0mrfp258BIsZOQBeAHzIZ8xSvWaRDAAriDiwBQg5BSoYBxcPPx4yGAAngAOEPwAzmBQrMrIalLesgpKZkQAkFAMwVBRecEQqkQaRMQIkbnI2PwGmHq4bpVVlnQMzCAs- JSx6q1dID3G-Ri6SKYjhNXj1lMz0fNtrUA

私には、どちらのインターフェースも定義が同じで、表記が違うだけだと思います。

もしこれがTypeScriptのバグではなく、本当の理由があるのなら、2つ目の質問に移ろう。 doSomething"はオプションで、関数かRegExpのどちらかであることを指定する必要がある。

interface InterfaceB {
  doSomething?: ((data: object) => boolean) | RegExp;
}`

InterfaceAの記法で、どうすれば実現できるのでしょうか?

どのように解決するのですか?

1.) という違いがあります。 メソッド 関数プロパティ を宣言します。

interface InterfaceA {
  doSomething(data: object): boolean; // method declaration
}

interface InterfaceB {
  doSomething: (data: object) => boolean; // function as property declaration
}

2.) TypeScript 2.6 は、より強い型付けを行うためのコンパイラフラグを導入しています。 サウンド 関数の型があります。

--strictFunctionTypes 関数型パラメータの位置がチェックされる 二変量ではなく、対数変量 . その より厳格なチェック が適用されます。 すべての関数型 , ただし に由来するもの。 メソッドまたはコンストラクタの宣言 . (私の強調)

一般的にそれは良いことなんですね。あなたの例で言えば InterfaceB は次のような契約を結んでいます: "一般的な object は互換性があります" 。しかし、ある関数に doIt を期待するものである。 特定 オブジェクトの型は { type: string; } を入力とする。を使用するクライアントは InterfaceB を渡すだけで十分だと考えています。 object しかし、実装 doIt はより具体的なものを望んでいるので、当然のことながらこのエラーが発生します。

でエラーが発生しないのはなぜでしょう? InterfaceA ?

それに対して メソッド のように doItInterfaceA 除く から --strictFunctionTypes というのは、実用的な理由からです。の組み込みメソッドであまりペンダントにならないような型システムを開発者は決定しました。 Array など、正しさと生産性を両立させるために、様々な工夫が凝らされています。

そこで、より強い型を優先して、あなたの場合に有効な次のような型がいいと思います( サンプル ):

interface InterfaceB {
  doSomething: ((data: { type: string; }) => boolean) | RegExp;
}