【问题标题】:Typeof Class in not assignable to classTypeof Class in 不可分配给类
【发布时间】:2018-10-27 19:38:31
【问题描述】:

这是一些示例代码,我无法弄清楚它为什么会引发错误。 任何相同的帮助将不胜感激。 我试图在 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);

【问题讨论】:

    标签: typescript typescript-typings


    【解决方案1】:

    问题在于 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);
    

    【讨论】:

    • 好的,谢谢。这是一个很好的答案。只是想知道我是否替换 'new (args: any) => Ab | Ac' 与 enumClass 我得到一个错误,是否有任何解决方法。可以使用 as 对其进行类型转换,但感觉不对。有什么相同的建议吗?
    • 错误是因为 enumClass 等于 typeof Ab |本例中的类型为 Ac。但目前我不知道如何恢复 typeof。
    • 好吧,我们不需要在第一种方法中指定 typeof。在这方面有什么建议吗?
    • 井接缝除了用 as 没有别的办法。无论如何感谢所有的帮助。
    • 也许其他任何人都可以找到一种无需强制转换的方式来键入此内容。但这里的演员是安全的。我不知道为什么这里没有正确推断出来。但是没有泛型 new enumClassMap[enumMap.Ab]({a: "a") 被正确推断为 Ab
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    • 2017-09-25
    相关资源
    最近更新 更多