打字稿 - 工厂模式

zhuber

我正在尝试为MainType. 我还想重用已经创建的类型(实际上我需要相同的实例),所以我将它们存储在ItemFactory.

class BaseType {

}

class MainType extends BaseType {

}

class ItemFactory {
    items: { [type: string]: BaseType } = {};

    get<T extends BaseType>(type: string): T | null {
        let item = this.items[type];

        if (!item) {
            switch (type) {
                case "main-type":
                    item = new MainType();
                    break;
                default:
                    return null;
            }

            this.items[type] = item;
        }

        return item as T;
    }
}

有没有办法简化通话

itemFactory.get<MainType>("main-type"); // current call

// option 1
const resolvedType = itemFactory.get<MainType>();

// option 2
const resolvedType = itemFactory.get("main-type");

我想要选项 1 或选项 2(两者都不需要),所以我不必同时传递标识符和类型来正确解析结果类型。

杰卡兹

您需要在传递给的名称itemFactory.get()和预期的输出类型之间为编译器提供某种映射从名称到类型的映射是interfaces 最擅长的,因此您可以像这样定义一个:

interface NameMap {
  "main-type": MainType;
  // other name-type mappings here
}

然后你把你的get()方法改成这样:

  get<K extends keyof NameMap>(type: K): NameMap[K] | null {
    let item = this.items[type];

    if (!item) {
      switch (type) {
        case "main-type":
          item = new MainType();
          break;
        default:
          return null;
      }

      this.items[type] = item;
    }

    return item as NameMap[K];
  }

你替换T extends BaseTypeNameMap[K]where K extends keyof NameMap现在以下(“选项 2”)将起作用:

const resolvedType = itemFactory.get("main-type"); // MainType | null

请注意,您永远不会让“选项 1”起作用。当 JS 被发出时,TypeScript 的类型系统会被删除,所以这个:

itemFactory.get<MainType>();

将在运行时变成这样:

itemFactory.get();

有没有办法让知道什么回报,因为相关资料已经落伍之前的代码开始运行。这是故意的;它是不是打字稿的目标为“在程序基于该类型系统的结果添加或依靠运行时类型信息,或发出不同的代码。” 相反,TypeScript 应该“鼓励不需要运行时元数据的编程模式”……在这种情况下,这意味着使用像字符串这样的运行时值"main-type"而不是像MainType跟踪get()应该做什么的设计时类型


好的,希望有帮助。祝你好运!

代码链接

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章