2015-10-17 74 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