首页 > 解决方案 > 如何在 Typescript (Nodejs/Deno) 中在运行时动态初始化类实例

问题描述

我正在使用 Deno 和 Typescript;假设在此示例中我有一个名为“A”的主类。我想要一些具有独特方法的其他类来扩展这个类'A'

就像:

class A {
   name: string,
   ...random props

   constructor(_name: string) {
      this.name = _name;
   }

   ...some generic methods(): {}
}


class B extends A {
   specialMethodOne() {
      some code ...
   }
}

class C extends A {
   specialMethodTwo() {
      some code ...
   }
}

class D extends A {
   specialMethodThree() {
      some code ...
   }
}


function Main() {
   const role = some async/await asking function(): string {
       "What role are you??"
        return role of some string (it would be 'B', 'C' or 'D')
   }

   const person = new **[role (B, C, or D)]**("Timmy");
}

所以在这种情况下,我想在运行时询问用户他们的“角色”,这与“B”、“C”或“D”类有关。然后使用他们返回的答案来初始化类。每个角色的类都有独特的方法。所以我不确定如何实现这一目标。

标签: javascripttypescriptclass

解决方案


您应该能够在测试角色字符串后实例化一个类。然后将返回类型设置为A | B | C. 最后,在调用任何特定于类的方法之前,必须测试返回的任何实例以查看它是什么类。

这是一个工作示例:

// Store role names as string somewhere
const ROLES = ['B', 'C', 'D'] as const

// Role base class
class A {
  name: string
  constructor(_name: string) {
    this.name = _name
  }
}

// Role specific classes
class B extends A {
  b(): string { return 'I am B'}
}
class C extends A {
  c(): string { return 'I am C'}
}
class D extends A {
  d(): string { return 'I am D'}
}

// Get a random role, for example sake.
function getRole(): 'B' | 'C' | 'D' {
  const index = Math.floor(Math.random() * ROLES.length)
  return ROLES[index]
}

// Get a random role, then instance the correct role class.
function Main(): A | B | C {
  const role = getRole()
  const myName = 'Timmy'

  let person: A | B | C
  if (role === 'B') person = new B(myName)
  else if (role === 'C') person = new C(myName)
  else if (role === 'D') person = new D(myName)
  else throw new Error(`Unknown role: ${role}`)

  return person
}

// Get a role instance. It could be an instance of B, C or D.
const roleInstance = Main()

// Test for the desired class before you call any class specific methods.
if (roleInstance instanceof B) roleInstance.b()
if (roleInstance instanceof C) roleInstance.c()
if (roleInstance instanceof D) roleInstance.d()

操场


我故意留下这个冗长的内容来说明正在发生的事情,但是可以进行很多重构。但是很难用这样一个人为的例子来提供更多建议。

例如,您为角色类创建角色名称字典,const roles = { A: A, B: B, C: C }然后创建类似new roles[getRole()]('Timmy'). 现在添加新的支持类非常容易。


推荐阅读