2017-09-10 11 views
0
interface DataGeneric { 
    value: number; 
} 

function transform<D extends DataGeneric>(data: DataGeneric[], get_value: (record: D) => number) { 

    // Works without error 
    let values = data.map(get_value); 
    // Following line errors with: 
    // Argument of type 'DataGeneric' is not assignable to parameter of type 'D'. 
    // 
    values = data.map(d => get_value(d)); 
    // Works without error, but why us type assertion needed? 
    values = data.map(d => get_value(d as D)); 
} 

get_valueに単一の値を渡すときに型アサーションが必要なのはなぜですか?ジェネリック型はmapの関数引数で動作しますが、単一の値ではありません

活字体2.3.4

答えて

1

あなたはDにキャストやエラーを取得する必要があります理由:

Argument of type 'DataGeneric' is not assignable to parameter of type 'D'

これはですか:

interface DataGeneric2 extends DataGeneric { 
    value2: string; 
} 

transform([{ value: 3 }], (record: DataGeneric2) => { 
    return record.value2.length; 
}); 

この例では、get_valueとして渡される関数は、DataGeneric2の値を取得し、DataGenericではなく値を取得することを想定しています。
これは、コンパイラがそれについて不平を言っているエラーです:
'DataGeneric'型の引数は、 'DataGeneric2'型のパラメータに代入できません。

Dにキャストする(または関数のシグネチャを変更する)と、コンパイラは自分が行っていることを知っていることを知っていることを確認します。

1

あなたはに関数のシグネチャを変更することにより、型アサーションを削除することができます。

function transform<D extends DataGeneric>(data: D[], get_value: (record: D) => number) { 
+0

あなたが求めていたことは?なぜあなたは元のコードにタイプアサーションが必要なのかを説明しなかったので –

+0

@NitzanTomerそれは本当に私が求めていたものではありません...私は答えとして投稿した解決策を見つけましたが、あなたはデータを 'D []'と定義しなければならないか、質問に示すように 'd as D'が必要なのです。 「あなたはなぜ型アサーションが必要なのか説明しなかった」と言って、 'd as D 'の型アサーションを使用しないとエラーが発生します:「型' DataGeneric 'の引数は型' D ' 'D extends DataGeneric'にもかかわらず。 – AJP