Typescript 子类类型(Type Assertions)

Posted

技术标签:

【中文标题】Typescript 子类类型(Type Assertions)【英文标题】:Typescript subclass type (Type Assertions) 【发布时间】:2016-01-16 08:27:06 【问题描述】:

我希望你喜欢动物。这是一个口语例子:

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

错误:“动物”类型不可分配给“猫”类型。 “动物”类型中缺少属性“妙欧”。

有人可以解释一下区别吗?我以为没有...

编辑: 好的,在打字稿规范中有详细说明:Type Assertions

class Shape  ... 
class Circle extends Shape  ... 
function createShape(kind: string): Shape 
 if (kind === "circle") return new Circle();
 ...

var circle = <Circle> createShape("circle");

【问题讨论】:

【参考方案1】:

“retrieveAnimal”函数返回一个“Animal”类型的对象,但是在这里

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

你声明了“Cat”类型的“retrievedCat”变量,所以你确实不能将 Animal 转换为 Cat。

第二种情况:

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

您声明“any”类型的“retrievedCat”变量(您没有指定任何类型,因此默认为“any”),并将值指定为“Cat”。显然,您可以将“Cat”转换为“any”,恕我直言。

【讨论】:

好的!但是如何使用那些不同的声明呢?为什么不只使用 seconde 声明?因此,我们可以使用 retrievedAnimal = ...谢谢! 视情况而定。如果您完全确定对象的类型,则可以通过“任何”类型(变体 2)进行转换。如果没有,您可以使用“instanceof”运算符(***.com/questions/12789231/…)检查类型。

以上是关于Typescript 子类类型(Type Assertions)的主要内容,如果未能解决你的问题,请参考以下文章

typescript 从子类调用的构造函数参数推断类型

即使我将其导出为 TypeScript 中自己的类型,也无法访问子类属性

Type[keyof Type] 函数参数的 Typescript 类型保护

[TypeScript] type、typeof、keyof

TypeScript系列教程16TypeScript 联合类型

TypeScript类型