2016-10-24 12 views
1

どのように質問をfomulateする方法がわからないが、これはそうである:TS:なぜ、有効でないタイプをジェネリックタイプの変数に割り当てることができますか?

interface X { 
    some: number 
} 

let arr1: Array<X> = Array.from([{ some: 1, another: 2 }]) // no error 
let arr2: Array<X> = Array.from<X>([{ some: 1, another: 2 }]) // will error 

code in playground

エラー:

Argument of type '{ some: number; another: number; }[]' is not assignable to parameter of type 'ArrayLike<X>'. 
    Index signatures are incompatible. 
    Type '{ some: number; another: number; }' is not assignable to type 'X'. 
     Object literal may only specify known properties, and 'another' does not exist in type 'X'. 

がなぜ最初のケースに誤りがありません(タイプの互換性チェックなし)、これは設計上のものか、それとも問題がありますか?

答えて

1

2つの配列インスタンスのタイプを見てみましょう。
我々は型定義奪う場合:(code in playground:種類を確認するために、配列変数をホバー)

// type of arr1 is { some: number; another: number; }[] 
let arr1 = Array.from([{ some: 1, another: 2 }]); 

// type of arr2 is X[] 
let arr2 = Array.from<X>([{ some: 1, another: 2 }]); 

を:

from<T>(arrayLike: ArrayLike<T>): Array<T>; 

Array.fromための署名があるためですコンパイラは、arr1に対して、関数に渡される値に基づいてジェネリック制約を推論するため、不平を言いません。
arr2の場合、総称制約はXに設定され、タイプは{ some: number; another: number; }と一致しません。

あなたはarr1Xを追加しようとするでしょう場合:

arr1.push({ some: 3 }); 

あなたが得られます。

Argument of type '{ some: number; }' is not assignable to parameter of type '{ some: number; another: number; }'. 
    Property 'another' is missing in type '{ some: number; }'. 
1

非常に非常に興味深い、私は知りませんでした。

強く型付けされた配列リテラルには、という既知の要素しか含まれていないようです。 エラーメッセージからは、バグではなく設計上のように見えます。

+0

この制限はアレイに限定されず、[この回答](http://stackoverflow.com/a/31816062/43848)で詳細に説明されています。 – artem

関連する問題