2017-08-16 26 views
0

我有以下代碼:打字稿接口的有一個錯誤

class Animal { 
    name: string; 
} 
class Dog extends Animal { 
    breed: string; 
} 

// Error: indexing with a 'string' will sometimes get you a Dog! 
interface NotOkay { 
    [x: number]: Animal; 
    [x: string]: Dog; 
} 

爲什麼界面「NotOkay」有錯誤。 但我嘗試更改如下界面:

interface NotOkay { 
     [x: string]: Animal; 
     [x: number]: Dog; 
    } 

錯誤消失。

+0

代碼。 HTML – Lulu

回答

0

在JavaScript(因此TypeScript)中,屬性鍵被強制爲string s。所以,如果你訪問屬性與number鍵,你實際上訪問屬性與string鍵:

var obj = {3: 'a', four: 'b'}; 
console.log(obj['3']); // a 
console.log(obj[3]); // a 
console.log(obj[3] === obj['3']); // true 

但也有一些string按鍵,是不是也number鍵:

console.log(obj['four']); // b 

因此,TypeScript編譯器強制返回值用於訪問number密鑰是訪問string密鑰的返回值的特例。例如,下面是好的:

interface Okay { 
    [x: string]: Animal; 
    [x: number]: Dog; 
} 

每次你訪問一個Okaynumber鍵,你居然還用string鍵訪問它。並且由於每個number關鍵屬性是Dog,並且每個string關鍵屬性是Animal,這就是說:每當您獲得Dog時,您實際上也獲得了Animal。這對編譯器來說是可驗證的。它知道DogAnimal的子類,並且每個DogAnimal。所以TypeScript很高興與Okay

但下面是不行的:

interface NotOkay { 
    [x: number]: Animal; 
    [x: string]: Dog; 
} 

每次你訪問一個NotOkaynumber鍵,你居然還用string鍵訪問它。並且由於每個number關鍵屬性是一個Animal,並且每個string關鍵屬性是一個Dog,這就是說:每當您得到一個Animal時,您實際上也獲得一個Dog。這是而不是對於編譯器是可驗證的;不是每個Animal必然是Dog,所以TypeScript是不高興NotOkay和抱怨。

希望有所幫助。

0

難道你不是在誤解索引簽名嗎?你希望達到什麼目的?

interface Okay { 
    name: string 
    size: number 
    [propName: string]: any 
} 

這意味着Okay可以具有任何數量的屬性,包括狗和動物:HTTPS://www.typescriptlang.org/docs/handbook/interfaces從

// o needs name and size and can have anything else optionally 
let o:Okay = {name:'billy', size:2, dog:new Dog(), animal:new Animal()}