首页 > 解决方案 > 按标准的通用工厂方法

问题描述

我想使用打字稿构建一个通用工厂方法。\

我的目标是使用泛型按名称实例化一个类,而不是使用 if/else/switch 语句。

我想实现相同的功能,例如:

document.createElement("p");

createElement<K extends keyof HTMLElementTagNameMap>(tagName: K, options?: ElementCreationOptions): HTMLElementTagNameMap[K];

interface HTMLElementTagNameMap {
    "a": HTMLAnchorElement;
    "abbr": HTMLElement;
    "address": HTMLElement;
    "applet": HTMLAppletElement;
...
}

我在尝试从类类型创建实例时遇到了困难:

class A {

  constructor(private name:string,private id:number){

  }
}

class B extends A{

}

class C extends A{

}



interface stringToClassMap{
  'A':A;
  'B':B;
  'C':C;
}

// Need to be new instance every time
const obj: stringToClassMap = {A:new A('x',123),B:new B('x',123),C:new C('x',123)}

function creator<K extends keyof stringToClassMap>(key:K): A{
  return new obj[key]();<--------------------- 
}

谢谢!!!

标签: typescript

解决方案


class Y {
  constructor(public a: string) {}
}

class A {
  constructor(private name: string, private id: number) {}
}

class B extends A {}

class C extends Y {}

type Constructor<T> = new (...args: any) => T;
interface ClassNameMap {
  A: Constructor<A>;
  B: Constructor<B>;
  C: Constructor<C>;
  Y: Constructor<Y>;
}
// Need to be new instance every time
const obj: ClassNameMap = {
  A: A,
  B: B,
  C: C,
  Y: Y
};

function creator<K extends keyof ClassNameMap>(
  key: K,
  ...options: any
): ClassNameMap[K] extends Constructor<infer M> ? M : never {
  const Cls = obj[key];
  return new Cls(...options) as any;
}

const t = creator("A", "");
const b = creator("B", "");
const c = creator("C", "");
const y = creator("Y", "");

推荐阅读