Typescript-gränssnittsimplementation har ingen effekt på indexsignatur
För mitt nya lilla projekt bestämde jag mig för att använda TypeScript av en anledning som inte är bättre än att få mig att känna att jag programmerar i C på remarkabla steroider och uppenbarligen betalar jag priset.
Jag har ett gränssnitt, eller hur
export default interface DataObject {
[key: string]: any
};
Vilket tydligen tillåter mig att definiera objekt med strängnycklar och vilka värden som helst. Sedan implementerar jag det
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];
}
}
}
Nu får jag detta fel
Element har implicit typen 'any' eftersom typen 'Model' inte har någon indexsignatur
på den här raden
model[prop] = data[prop];
Men om jag ändrar min modell för att inkludera signaturen
import DataObject from "./data-object";
export default class Model implements DataObject {
[key: string]: any;
...
}
Då finns det inget fel.
Varför har inte gränssnittets signatur någon effekt på min klass?
Svar #1
Jag tror att gränssnitt inte har någon påverkan på implementeringen. Om du ändrar det till en klass och ärver den så fungerar det som förväntat. Det beror på att du kan implementera indexet på ett annat sätt, som egenskaper, se exemplet (i 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
}
}
}
