首页 > 解决方案 > 如何根据 Typescript 中的类类型动态实例化类数组

问题描述

我实施了如下策略模式

interface IRule {
  isMatch(n: number): boolean;
}

class Rule1 implements IRule {
  isMatch(n: number) {
    return n === 7;
  }
}

class Rule2 implements IRule {
  isMatch(n: number) {
    return n % 2 === 0;
  }
}

class Factory {
  readonly rules: IRule[];

  constructor() {
    this.rules = [new Rule1(), new Rule2()];
  }

  public of(n: number) {
    return this.rules.find(r => r.isMatch(n));
  }
}

const found = new Factory().of(7);

问题:
TypeScript 中有没有一种方法Factory.Rules可以根据类类型动态创建IRule

在 C# 中,这可以按如下方式完成:

var ruleTypeInterface = typeof(IRule);
var rulesType = Assembly.GetExecutingAssembly()
                        .GetTypes()
                        .Where(t => ruleTypeInterface.IsAssignableFrom(t) && t.IsClass);
this.rules = rulesType.Select(rt => Activator.CreateInstance(rt) as IRule).ToArray();

标签: typescriptreflectiondependency-injectionfactorystrategy-pattern

解决方案


你在正确的轨道上,但有一些语法错误。

class Rule1: IRule {
  isMatch(in: number) {
    return number === 7;
  }
}

当你有一个class实现interface你写的class Rule1 implements IRule而不是class Rule1: IRule.

in是你的isMatch方法中的变量名并且number是类型,但是你使用number它就好像它是变量名一样。 in也是保留字,所以我们n改用。

Factory有相同的in保留字问题。它也有一个错误A class member cannot have the 'const' keyword。也许你想成功readonly

interface IRule {
  isMatch(n: number): boolean;
}

class Rule1 implements IRule {
  isMatch(n: number) {
    return n === 7;
  }
}

class Rule2 implements IRule {
  isMatch(n: number) {
    return n % 2 === 0;
  }
}

class Factory {
  readonly rules: IRule[];

  constructor() {
    this.rules = [new Rule1(), new Rule2()];
  }

  public of(n: number) {
    return this.rules.find(r => r.isMatch(n));
  }
}

const found = new Factory().of(7);

这一切现在都有效。推断的类型foundIRule | undefined因为我们不知道(仅基于类型)是否of会找到匹配项。

打字稿游乐场链接


推荐阅读