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

อินเทอร์เฟซของคอนสตรัคเตอร์ในไทป์สคริปต์


ฉันได้ยกตัวอย่างนี้มาจากเอกสาร

interface ClockConstructor {
  new (hour: number, minute: number): ClockInterface;
}

interface ClockInterface {
  tick(): void;
}

function createClock(
  ctor: ClockConstructor,
  hour: number,
  minute: number
): ClockInterface {
  return new ctor(hour, minute);
}

class DigitalClock implements ClockInterface {
  constructor(h: number, m: number) {}
  tick() {
    console.log("beep beep");
  }
}

class AnalogClock implements ClockInterface {
  constructor(h: number, m: number) {}
  tick() {
    console.log("tick tock");
  }
}

let digital = createClock(DigitalClock, 12, 17);
let analog = createClock(AnalogClock, 7, 32);

ตามที่เอกสารกล่าวว่า:

เนื่องจากพารามิเตอร์ตัวแรกของ createClock เป็นชนิด ClockConstructor ใน createClock(AnalogClock, 7, 32) มันจะตรวจสอบว่า AnalogClock มีลายเซ็นของตัวสร้างที่ถูกต้อง

ฉันสงสัยว่าทำไมจึงไม่มีการจำกัดเกี่ยวกับการไม่มีคอนสตรัคเตอร์ ดังนั้นถ้าฉันเปลี่ยนคลาส AnalogClock ดังนี้ Typescript ก็จะไม่แจ้งข้อผิดพลาดใด ๆ

class AnalogClock implements ClockInterface {
    // constructor(h: number, m: number) {}  <-- this like commented out.
    tick() {
      console.log("tick tock");
    }
  }

คำตอบ #1

ถ้าคุณไม่ระบุตัวสร้าง (constructor) โดยตรง ตัวสร้างเริ่มต้นจะถูกใช้แทนตามเอกสารของ MDN

class AnalogClock implements ClockInterface {
  tick() {
    console.log("tick tock");
  }
}

// is equal to
class AnalogClock implements ClockInterface {
  constructor() {}

  tick() {
    console.log("tick tock");
  }
}

นอกจากนี้ ตัวสร้างจะสืบทอดการเรียก super(...args) หากคุณไม่ระบุตัวสร้างในคลาสลูก

class Ancestor {
  foo: string;
  
  constructor(foo: string) {
    this.foo = foo;
  }
}

class Child extends Ancestor {
  constructor(foo: string) {
    super(foo);
  }
}

// equals to
class Child extends Ancestor {}

ลิงก์สนามเด็กเล่น