Typescript 类型脚本-工厂模式

Typescript 类型脚本-工厂模式,typescript,generics,types,type-conversion,factory,Typescript,Generics,Types,Type Conversion,Factory,我正在尝试为MainType创建工厂。我还想重用已经创建的类型(实际上我需要相同的实例),所以我将它们存储在ItemFactory中 class BaseType { } class MainType extends BaseType { } class ItemFactory { items: { [type: string]: BaseType } = {}; get<T extends BaseType>(type: string): T | null

我正在尝试为
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;
    }
}
类基类型{
}
类MainType扩展了BaseType{
}
类项工厂{
项:{[type:string]:BaseType}={};
get(类型:string):T | null{
设item=this.items[type];
如果(!项){
开关(类型){
案例“主要类型”:
item=新的MainType();
打破
违约:
返回null;
}
此.项目[类型]=项目;
}
返回项目为T;
}
}
有没有办法简化通话

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

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

// option 2
const resolvedType = itemFactory.get("main-type");
itemFactory.get(“主类型”);//当前通话
//选择1
const resolvedType=itemFactory.get();
//选择2
const resolvedType=itemFactory.get(“主类型”);

我希望使用选项1或选项2(两者都不需要),因此我不必同时传递标识符和类型来正确解析结果类型。

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

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];
  }

请注意,您将永远无法使用“选项1”。TypeScript的类型系统在发出JS时获取,因此:

itemFactory.get<MainType>();
因为在代码开始运行之前,相关信息已经被留下了,所以它无法知道返回什么。这是故意的;它是“在程序中添加或依赖运行时类型信息,或根据类型系统的结果发出不同的代码。”相反,TypeScript应该“鼓励不需要运行时元数据的编程模式”。。。在这种情况下,它意味着使用一个运行时值,如字符串
“main type”
,而不是设计时类型,如
main type
,来跟踪
get()
应该做什么


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


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

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];
  }

请注意,您将永远无法使用“选项1”。TypeScript的类型系统在发出JS时获取,因此:

itemFactory.get<MainType>();
因为在代码开始运行之前,相关信息已经被留下了,所以它无法知道返回什么。这是故意的;它是“在程序中添加或依赖运行时类型信息,或根据类型系统的结果发出不同的代码。”相反,TypeScript应该“鼓励不需要运行时元数据的编程模式”。。。在这种情况下,它意味着使用一个运行时值,如字符串
“main type”
,而不是设计时类型,如
main type
,来跟踪
get()
应该做什么


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