2015-10-17 238 views
0

我希望你喜歡動物。這是一個演講的例子:Typescript子類型(Type Assertions)

class Animal { 
    constructor(public name: string, public age: number) {} 
} 

class Cat extends Animal { 
    constructor(name: string, age: number) { 
    super(name, age); 
    } 
    public miaou() { 
    console.log('Miaou'); 
    } 
} 

class Kennel { 
    animals = Map<string, Animal> new Map(); 

    public addAnimal(animal: Animal): void { 
    this.animals.set(animal.name, animal); 
    } 

    public retrieveAnimal(name: string): Animal { 
    return this.animals.get(name); 
    } 
} 

let kennel = <Kennel> new Kennel(); 
let hubert = <Cat> new Cat('Hubert', 4); 

kennel.addAnimal(hubert); 

let retrievedCat: Cat = kennel.retrieveAnimal('Hubert'); // error 
let retrievedCat = <Cat> kennel.retrieveAnimal('Hubert'); // Works 

錯誤:類型'動物'是不可分配類型'貓'。屬於'動物'的屬性'Miaou'缺失。

有人可以解釋我的區別?我認爲有沒有...

編輯: OK,它在打字稿規範中詳細說明:Type Assertions

class Shape { ... } 
 
class Circle extends Shape { ... } 
 
function createShape(kind: string): Shape { 
 
if (kind === "circle") return new Circle(); 
 
... 
 
} 
 
var circle = <Circle> createShape("circle");

回答

0

的 「retrieveAnimal」 函數返回一個對象「動物」類型,但這裏是

let retrievedCat: Cat = kennel.retrieveAnimal('Hubert'); 

你聲明瞭「Cat」類型的「retrieveCat」變量,所以你確實無法將Animal轉換爲Cat。

在第二種情況:

let retrievedCat = <Cat> kennel.retrieveAnimal('Hubert'); 

聲明瞭「任何」類型的「retrievedCat」變量(你不指定任何類型的,所以默認 - 「任意」),並指定值作爲「貓」。顯然,你可以將「Cat」投射到「任何」,恕我直言。

+0

好的!但是,如何使用這些不同類型的聲明?爲什麼不使用seconde聲明?因此,我們可以使用retrieveAnimal = ... 謝謝! – Tiramitsu

+0

這取決於。如果你對物體的類型非常熟悉,你可以通過「任何」類型投射(變體2)。如果沒有,你可以使用「instanceof」運算符來檢查類型(http://stackoverflow.com/questions/12789231/class-type-check-with-typescript)。 – TSV