ค้นหาเว็บไซต์

การใช้งานอินเทอร์เฟซของ Typescript ไม่มีผลต่อดัชนีลายเซ็น


สำหรับโครงการเล็ก ๆ ใหม่ของฉัน ฉันตัดสินใจใช้ 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];
    }
  }
}

ตอนนี้ฉันได้รับข้อผิดพลาดนี้

องค์ประกอบมีชนิด 'any' โดยปริยายเพราะชนิด 'Model' ไม่มีลายเซ็นดัชนี

บนเส้นนี้

      model[prop] = data[prop];

แต่ถ้าฉันปรับโมเดลของฉันให้รวมลายเซ็นด้วย

import DataObject from "./data-object";

export default class Model implements DataObject {

  [key: string]: any;

  ...
}

แล้วก็ไม่มีข้อผิดพลาด

ทำไมลายเซ็นของอินเทอร์เฟซจึงไม่มีผลต่อคลาสของฉัน?

คำตอบ #1

ฉันคิดว่าคอนสตรัคเตอร์ไม่มีผลต่อการทำงานจริง ถ้าคุณเปลี่ยนมันเป็นคลาสและสืบทอดมัน จะทำงานตามที่คาดหวัง นั่นเป็นเพราะคุณสามารถทำดัชนีให้ทำงานในแบบอื่นได้ เช่น ผ่านพร็อพเพอร์ตี้ ดูตัวอย่าง (ใน 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
        }
    }
}

บทความที่เกี่ยวข้อง