2017-02-17 26 views
1

有了這個接口聲明:Typescript索引屬性約束檢查工作原始類型但不是對象文字?

interface Thing1 { 
    [key: string]: string; 
    x: number; 
} 

打字稿,在編譯時,拋出一個錯誤「TS2411:房產‘X’的類型編號是不能分配給字符串索引類型‘字符串’」

聽起來合法。

但是,只要我使用對象文本作爲我的索引類型值:

interface Foo {} 
interface Thing2 { 
    [key: string]: Foo; 
    foo: number; 
} 

...它不抱怨了,這聽起來有些不可思議我爲number仍然是一個不同的類型Foo

對此背後原因有何想法?

注意:使用打字稿2.1.5

回答

1

這是由於方式type compatibility作品打字稿:在打字稿

類型兼容性是基於結構亞型。結構打字是僅基於成員關聯類型的一種方式。這與名義打字相反。

所以,這個工程:

interface Foo {} 
let f: Foo = 3; 

由於對{}每個屬性,也具有相同名稱的屬性和類型Number

這意味着,這不起作用:

interface Foo {} 
let f: Foo = 3; 
let b: number = f; 

編譯器抱怨let b: number = f;

類型 '富' 是不能分配給輸入 '號';

再次,從文檔:

打字稿的結構類型系統是基於怎樣的JavaScript代碼通常寫入設計。由於JavaScript廣泛使用函數表達式和對象文字等匿名對象,因此使用結構類型系統而不是名義類型代表JavaScript庫中存在的各種關係更爲自然。

+0

我意識到結構分型的,但是,我從來沒有想過一個數量將有完全相同的「結構」(在其API的方面)作爲對象常量。 奇怪。 :-) –

+0

@Frédéric要清楚,一個數字並不具有相同的結構,只是對於'{}'上的每個屬性,'Number'上都有一個與其名稱和類型相同的屬性。我會澄清答案。 – Seamus

1

空接口與簡單類型(數字,字符串)兼容。

let c: Foo = 3; 

因此,在Thing2打字稿推理仍將看到美孚與數量兼容:如果你寫這個打字稿不會抱怨。但是,當索引簽名像Thing1中的字符串時,所有成員都應該是字符串(如您所述)。