首页 > 解决方案 > Typeof Class in 不可分配给类

问题描述

这是一些示例代码,我无法弄清楚它为什么会引发错误。任何相同的帮助将不胜感激。我试图在 getClass 函数中创建一个类实例,但打字稿抛出了一些错误。代码在 javascript 中运行,但我无法找到修复打字稿错误的方法。

它是说“类型'typeof Ab'不可分配给类型'Ab'。类型'typeof Ab'中缺少属性'b'”。

class A {
    public a: string
    constructor(args: Partial<A>) {
        this.a = args.a;
    }
};

class Ab extends A {
    public b: string
    constructor(args: Partial<Ab>) {
        super(args);
        this.b = args.b;
    }
};

class Ac extends A {
    public c: string
    constructor(args: Partial<Ac>) {
        super(args);
        this.c = args.c;
    }
};

const enumMap = {
    ab: 1 as 1,
    ac: 2 as 2,
};

type enumMap = typeof enumMap[keyof typeof enumMap];

type enumClass<T extends enumMap> =
    T extends typeof enumMap.ab ? Ab :
    T extends typeof enumMap.ac ? Ac : never;

const enumClassMap: { [K in enumMap]: enumClass<K> } = {
    [enumMap.ab]: Ab, //Error
    [enumMap.ac]: Ac, //Error
}

function getClass<T extends enumMap>(type: T) {
    let abc: { new(): enumClass<T> } = enumClassMap[type];
    return new abc({});
};

getClass(enumMap.ac);

标签: typescripttypescript-typings

解决方案


问题是 enumClassMap 需要一个 Ab 和 Ac 类的对象:

const enumClassMap: { [K in enumMap]: enumClass<K> } = {
    [enumMap.ab]: new Ab({a: "a", b: "b"}), //Error
    [enumMap.ac]: new Ac({a: "a", c: "c"}), //Error
}

我认为这应该是您问题的正确输入:

type enumClass<T extends enumMap> = T extends typeof enumMap.ab ? typeof Ab 
    : T extends typeof enumMap.ac ? typeof Ac : never;

function getClass<T extends enumMap>(type: T) {
  let abc: (new (args: any) => Ab | Ac) = enumClassMap[type];
  return new abc({a: "a"});
};

更新:

这将是键入您的示例的另一个示例。但我不知道为什么演员阵容是必要的。索引类型的类型推断似乎存在一些问题。

class A {
  public a: string;
  constructor(args: Partial<A>) {
    this.a = args.a;
  }
}

class Ab extends A {
  public b: string;
  constructor(args: Partial<Ab>) {
    super(args);
    this.b = args.b;
  }
}

class Ac extends A {
  public c: string;
  constructor(args: Partial<Ac>) {
    super(args);
    this.c = args.c;
  }
}

enum enumMap {
  Ab = 1,
  Ac
}

type enumClass<T extends enumMap> = T extends typeof enumMap.Ab
  ? Ab
  : T extends typeof enumMap.Ac ? Ac : never;

interface ConstructorOf<T extends enumMap> {
  new (args: any): enumClass<T>;
}

const enumClassMap: { [T in enumMap]: ConstructorOf<T> } = {
  [enumMap.Ab]: Ab,
  [enumMap.Ac]: Ac
};

function getClass<T extends enumMap>(type: T) {
  return new enumClassMap[type]({a: "a"}) as enumClass<T>;
}

getClass(enumMap.Ac);

推荐阅读