2016-10-24 90 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

讓我們來看看兩個數組實例的類型。
如果我們帶走的類型定義:

// 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 }]); 

code in playground:懸停數組變量看類型)

這是因爲Array.from的簽名是:

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

的編譯器不會抱怨arr1,因爲它會根據傳遞給該函數的值推斷通用約束。
但是在arr2的情況下,通用約束設置爲X,並且類型{ some: number; another: number; }與它不匹配。

如果你嘗試添加Xarr1

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

相關問題