Typescript 接口实现对索引签名没有影响

Typescript interface implementation has no effect on index signature

对于我的新小项目,我决定使用 TypeScript 的原因无异于让自己感觉像在显着的类固醇上编程 C 并且显然我付出了代价。

我有接口对吧

export default interface DataObject {
  [key: string]: any
};

这应该允许我使用字符串键和任何值定义对象。那我来实现一下

import DataObject from "./data-object";

export default class Model implements DataObject {

  constructor(data: DataObject = {}) {
    Model.fill(this, data);
  }

  static fill(model: Model, data: DataObject) {
    for (let prop in data) {
      model[prop] = data[prop];
    }
  }
}

现在我收到这个错误

Element implicitly has 'any' type because type 'Model' has no index signature

这条线

      model[prop] = data[prop];

但是如果我修改我的模型以包含签名

import DataObject from "./data-object";

export default class Model implements DataObject {

  [key: string]: any;

  ...
}

那就没有错误了

为什么接口签名对我的class没有影响?

我认为接口对实现没有影响。如果您将它更改为 class 并扩展它,它会按预期工作。那是因为你可以用另一种方式实现索引,比如属性,见例子(在Playground)。

interface DataObject {
    foo: any;
    bar: any;
    [key: string]: any;
};

class Model implements DataObject {

    private _bar: string = null;
    public get bar(): string {
        return this._bar;
    }
    public set bar(value: string) {
        this._bar = value;
    }

    constructor(data: DataObject = {}) {
        this.foo = "bar"; // error
        this.bar = "foo"; // no error
        Model.fill(this, data);
    }

    static fill(model: Model, data: DataObject) {
        for (let prop in data) {
            model[prop] = data[prop]; // error
        }
    }
}

class DataObject2 {
    foo: any;
    bar: any;
    [key: string]: any;
};

class Model2 extends DataObject2 {

    constructor(data: DataObject2 = { foo: "", bar: "" }) {
        super();
        this.foo = "bar"; // no error
        this.bar = "foo"; // no error
        Model2.fill(this, data);
    }

    static fill(model: Model2, data: DataObject2) {
        for (let prop in data) {
            model[prop] = data[prop]; // no error
        }
    }
}