尝试分配接口时出错

时间:2018-03-07 00:50:49

标签: typescript typescript2.0

我有以下类/接口:

class Klass {
  baseAttr: string;
}

class ChildKlass extends Klass {
  childAttr: string;
}

interface T1<T extends Klass = Klass> {
  readonly display: ReadonlyArray<keyof T>;
}

class T1Klass implements T1<ChildKlass> {
  readonly display: ReadonlyArray<keyof ChildKlass> = ['childAttr'];
}

上面的一切都很好......

当我尝试创建一个&#34;字典&#34;值应该是:

t1 - &#34;实现T1&#34;;类的实例 klass - &#34;扩展Klass&#34;

的类实例
interface ConstructableT1 {
  new(): T1;
}

interface T1KlassDictionary {
  [key: string]: {
    // Since I can't just say t1 is typeof T1, I created the ConstructableT1 interface
    t1?: ConstructableT1,
    klass?: typeof Klass
  };
}

当我尝试实例化object

const dictionary: T1KlassDictionary = {
  test: {
    t1: T1Klass,
    klass: ChildKlass
  }
};

...它给了我以下错误:

  

Type&#39; typeof T1Klass&#39;不能分配给&#39; ConstructableT1&#39;。

Playground link

我做错了什么?

1 个答案:

答案 0 :(得分:1)

  

Type&#39; typeof T1Klass&#39;不能分配给&#39; ConstructableT1&#39;。

TypeScript编译器有时会缩短错误消息。在这种情况下,它没有说明为什么(flavor == "vanilla" && flavor == "chocolate")无法分配给typeof T1Klass

要了解原因,请尝试将其中一个分配到另一个:

ConstructableT1

现在我们得到

let a: typeof T1Klass;
let b: ConstructableT1 = a;

这似乎是合理的 - 一个可能的关键价值 - &#34; id&#34; - 不能赋予文字类型的值&#34; attr&#34;。

一种可能的解决方案是使Type 'typeof T1Klass' is not assignable to type 'ConstructableT1'. Type 'T1Klass' is not assignable to type 'T1<Klass>'. Types of property 'display' are incompatible. Type 'ReadonlyArray<"id" | "attr">' is not assignable to type 'ReadonlyArray<"attr">'. Type '"id" | "attr"' is not assignable to type '"attr"'. Type '"id"' is not assignable to type '"attr"'. 通用,因此编译器将知道interface ConstructableT1的实际类型,并且不会使用不兼容的泛型参数(t1)的默认值:< / p>

T1Klass

更新问题得到澄清:

  

当我尝试创建一个&#34;字典&#34;价值所在   应该是:

     

t1 - &#34;实现T1&#34;的类的实例; klass - &#34;一个实例   扩展Klass&#34;

的类

然后我说你的interface T1<T extends Klass = Klass> { readonly display: ReadonlyArray<keyof T>; } interface ConstructableT1<T extends Klass = Klass> { new(): T1<T>; } class T1Klass implements T1<ChildKlass> { readonly display: ReadonlyArray<keyof ChildKlass> = ['id']; } class Klass { attr: string; } class ChildKlass extends Klass { id: string; } interface T1KlassDictionary { [key: string]: { t1?: ConstructableT1<ChildKlass>, klass?: typeof Klass }; } const dictionary: T1KlassDictionary = { test: { t1: T1Klass, klass: ChildKlass } }; t1类型错误。您将它们声明为构造函数 - 也就是说,klass可用于创建此类

之类的实例
dictionary.t1

游乐场说,以这种方式创建的const inst = new dictionary.test.t1(); 类型为inst

如果字典应该包含实例,则应该像这样声明

const inst: T1<ChildKlass>

并使用interface T1KlassDictionary { [key: string]: { t1?: T1<ChildKlass>, klass?: Klass }; }

创建的实例初始化
new()

然后您可以访问实例属性:

const dictionary: T1KlassDictionary = {
    test: {
        t1: new T1Klass(),
        klass: new ChildKlass()
    }
};