Typescript中以变量方式传递类

时间: 2020-04-07阅读: 224标签: Typescript

最近尝试用TypeScript写一个工具库,需要实现这样一个场景:

  1. 声明一个抽象类Parent
  2. 声明一组子类ChildA、ChildB继承这个Parent,实现它的抽象方法
  3. 实现一个方法,根据参数返回对应的子类
  4. 用拿到的子类创建实例

代码示例如下:

abstract class Animal {
  abstract makeSound(): void
}
class Dog extends Animal {
  makeSound(): void {
    console.log('woof')
  }
}
class Cat extends Animal {
  makeSound(): void {
    console.log('meow')
  }
}
const getAnimal = (name: string) => {
  if (name === 'cat') return Cat
  return Dog
}

const animal = new (getAnimal('dog'))()
animal.makeSound()  // woof

首先注意new后面getAnimal方法的执行需要用括号包起来,否则将得到以下错误:

TS2350: Only a void function can be called with the 'new' keyword.
ESLint: A constructor name should not start with a lowercase letter.

随后按照严谨的做法,我尝试给这个getAnimal方法添加类型约束:

const getAnimal = (name: string): Animal => {
  if (name === 'cat') return Cat
  return Dog
}

马上得到了错误提示:

TS2351: This expression is not constructable. 
Type 'Animal' has no construct signatures.

这样写的错误在于,Animal描述的应当是一个由其创建的实例的类型(或者说类)。

比如改写成下面这样就没有问题了:

const getAnimalInstance = (name: string): Animal => {
  if (name === 'cat') return new Cat()
  return new Dog()
}

而上面的getAnimal方法返回的不是实例,是类(构造器)本身。

描述这种类型,需要用到TypeScript的new ()语法

const getAnimal = (name: string): { new (): Animal } => {
  if (name === 'cat') return Cat
  return Dog
}

或者这样写:

const getAnimal = (name: string): new () => Animal => {
  if (name === 'cat') return Cat
  return Dog
}

表示这个方法返回的是一个构造器,这个构造器可以创造出一个类型是Animal的实例。

最后的示例如下:

abstract class Animal {
  abstract makeSound(): void
}
class Dog extends Animal {
  makeSound(): void {
    console.log('woof')
  }
}
class Cat extends Animal {
  makeSound(): void {
    console.log('meow')
  }
}
const getAnimal = (name: string): { new (): Animal } => {
  if (name === 'cat') return Cat
  return Dog
}

const getAnimalInstance = (name: string): Animal => {
  if (name === 'cat') return new Cat()
  return new Dog()
}

console.log('sound:', new (getAnimal('dog'))().makeSound())
console.log('sound:', getAnimalInstance('cat').makeSound())

打开在线示例查看执行结果:https://codepen.io/mirari/pen/xxbrvVd

点击Console打开控制台

参考文档:TypeScript-泛型-在泛型里使用类类型


站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/8859

抛弃 JS,使用 TypeScript

最近几个月我已经全面抛弃 JavaScript,完全使用 TypeScript 进行前端开发(只在上课的时候用到 JS)。先说优点:bug 显著减少,之前会遇到的 xxx 为空的问题几乎不会出

放弃 TypeScript 的 7 个非常好的理由

很多人都喜欢 TypeScript。它“解决”了 JS 的许多问题,是 JS 的一个“超集”,它将使代码易于阅读。有很多使用 TypeScript 的理由,但是我将给您 7 个不使用 TypeScript 的理由。

使用TypeScript两年后-值得吗?

差不多两年前,我在一个创业团队中开始了一个全新的项目。用到的全都是类似Microservices,docker,react,redux这些时髦的东西。我在前端技术方面积累了一些类似的经验

项目中使用 TypeScript 的一些感悟

抛开以前做业务的时候的不完全使用,这次实践可以算是我第一次真正意义上的使用 ts。由于写法上的不同,以及对不熟悉事物的新鲜感,在这次项目开发的过程中着实有着许多感悟,于是打算写篇小东西好好记录下来

谷歌为何会选用TypeScript?

谷歌在很早之前就张开双臂拥抱 Web 应用程序,Gmail 已经发布 14 年了。当时,JavaScript 的世界是疯狂的。Gmail 工程师不得不为 IE 糟糕的垃圾回收算法捏一把汗,他们需要手动将字符串文字从 for 循环中提取出来,以避免 GC 停顿

为什么要用TypeScript?

TypeScript的设计目的应该是解决JavaScript的“痛点”:弱类型和没有命名空间,导致很难模块化,不适合开发大型程序。另外它还提供了一些语法来帮助大家更方便地实践面向对象的编程。

10个帮助你捕获更多Bug的TypeScript建议

有一个对TypeScript常见的误解是:一个变量只要标注了类型,那么它总是会检查自己的数据类型是否与我们的预期一致。与该误解相呼应的想法会认为:对一个从后端返回的对象进行类型标注可以在代码运行时执行检查来确保对象类型的正确性。

TypeScript 是怎样工作的?

本文概述了 TypeScript 的工作原理:典型的 TypeScript 项目的结构是什么?什么被编译以及怎样编译?我们如何使用 IDE 编写 TypeScript?

TypeScript功能:const断言

我发现官方的 TypeScript 文档非常有用,但是总觉得有点过于学术化并且枯燥无味。每当我发现一个新功能时,我想要知道这个功能究竟能够解决什么问题而不是长篇大论

用TypeScript弥补Elm和JavaScript之间的差距

近些日子,我使用了新语言编程,从JavaScript,切确地说是Elm,转成TypeScript。在本文中,我将继续深挖一些我非常喜欢的TypeScript特性。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!

文章投稿关于web前端网站点搜索站长推荐网站地图站长QQ:522607023

小程序专栏: 土味情话心理测试脑筋急转弯幽默笑话段子句子语录成语大全运营推广