เป็นไปได้หรือไม่ที่จะใช้ getters / setters ในนิยามอินเตอร์เฟส


93

ในขณะTypeScriptนี้ไม่อนุญาตให้ใช้เมธอด get / set (accessors) ในอินเทอร์เฟซ ตัวอย่างเช่น:

interface I {
      get name():string;
}

class C implements I {
      get name():string {
          return null;
      } 
}

นอกจากนี้ TypeScript ไม่อนุญาตให้ใช้ Array Function Expression ใน class method: เช่น:

class C {
    private _name:string;

    get name():string => this._name;
}

มีวิธีอื่นใดบ้างที่ฉันสามารถใช้ getter และ setter ในนิยามอินเตอร์เฟสได้?

คำตอบ:


126

คุณสามารถระบุคุณสมบัติบนอินเทอร์เฟซได้ แต่คุณไม่สามารถบังคับว่าจะใช้ getters และ setters เช่นนี้:

interface IExample {
    Name: string;
}

class Example implements IExample {
    private _name: string = "Bob";

    public get Name() {
        return this._name;
    }

    public set Name(value) {
        this._name = value;
    }
}

var example = new Example();
alert(example.Name);

ในตัวอย่างนี้อินเทอร์เฟซไม่ได้บังคับให้คลาสใช้ getters และ setters ฉันสามารถใช้คุณสมบัติแทนได้ (ตัวอย่างด้านล่าง) - แต่อินเทอร์เฟซควรจะซ่อนรายละเอียดการใช้งานเหล่านี้อยู่ดีเนื่องจากเป็นสัญญากับรหัสการโทร เกี่ยวกับสิ่งที่สามารถโทรได้

interface IExample {
    Name: string;
}

class Example implements IExample {
    // this satisfies the interface just the same
    public Name: string = "Bob";
}

var example = new Example();
alert(example.Name);

และสุดท้าย=>ไม่อนุญาตให้ใช้วิธีการเรียน - คุณสามารถเริ่มการสนทนาเกี่ยวกับ Codeplex ได้หากคุณคิดว่ามีกรณีการใช้งานที่ไหม้ นี่คือตัวอย่าง:

class Test {
    // Yes
    getName = () => 'Steve';

    // No
    getName() => 'Steve';

    // No
    get name() => 'Steve';
}

1
คุณสามารถใช้=>เพื่อกำหนดเมธอดคลาสเช่นนี้name = (a: string) => this._name;แต่ในเอาต์พุต JS จะถูกกำหนดภายในฟังก์ชันคลาสแทนที่จะขยายอ็อบเจ็กต์ต้นแบบ
orad

ดูเหมือนจะใช้ไม่ได้กับคุณสมบัติรับแบบคงที่: /
CervEd

46

เพื่อเสริมคำตอบอื่น ๆ หากคุณต้องการกำหนดget valueอินเทอร์เฟซคุณสามารถใช้readonly:

interface Foo {
  readonly value: number;
}

let foo: Foo = { value: 10 };

foo.value = 20; //error

class Bar implements Foo {
  get value() {
    return 10;
  }
}

แต่เท่าที่ฉันทราบและตามที่คนอื่น ๆ กล่าวถึงตอนนี้ไม่มีวิธีใดในการกำหนดคุณสมบัติเฉพาะชุดในอินเทอร์เฟซ อย่างไรก็ตามคุณสามารถย้ายข้อ จำกัด ไปที่ข้อผิดพลาดรันไทม์ (มีประโยชน์ในระหว่างรอบการพัฒนาเท่านั้น):

interface Foo {
  /* Set Only! */
  value: number;
}

class Bar implements Foo {
  _value:number;
  set value(value: number) {
    this._value = value;
  }
  get value() {
    throw Error("Not Supported Exception");
  }
}

ไม่แนะนำการปฏิบัติ ; แต่เป็นตัวเลือก


2

ก่อนอื่น typescript สนับสนุนgetและsetไวยากรณ์เมื่อกำหนดเป้าหมาย Ecmascript 5 เท่านั้นเพื่อให้บรรลุสิ่งนี้คุณต้องเรียกคอมไพเลอร์ด้วย

tsc --target ES5

อินเทอร์เฟซไม่รองรับ getters และ setters หากต้องการรวบรวมโค้ดของคุณคุณจะต้องเปลี่ยนเป็น

interface I { 
    getName():string;
}

class C implements I { 
    getName():string {
          return null;
    }   
}

สิ่งที่ typescript รองรับคือไวยากรณ์พิเศษสำหรับฟิลด์ในตัวสร้าง ในกรณีของคุณคุณอาจมี

interface I {
    getName():string;
}

class C implements I {
    constructor(public name: string) {
    }
    getName():string {
        return name;
    }
}

สังเกตว่าคลาสCไม่ระบุฟิลด์nameอย่างไร มีการประกาศโดยใช้น้ำตาลวากยสัมพันธ์public name: stringในคอนสตรัคเตอร์

ดังที่ Sohnee ชี้ให้เห็นว่าจริงๆแล้วอินเทอร์เฟซควรจะซ่อนรายละเอียดการใช้งานใด ๆ ในตัวอย่างของฉันฉันได้เลือกอินเทอร์เฟซเพื่อต้องการเมธอด getter สไตล์ java อย่างไรก็ตามคุณยังสามารถใช้พร็อพเพอร์ตี้จากนั้นให้ชั้นเรียนตัดสินใจว่าจะใช้อินเทอร์เฟซอย่างไร


1
คุณสามารถใช้getและsetคำสำคัญใน TypeScript
เฟนตัน

หมายเหตุด้านข้างเกี่ยวกับการรองรับ ECMAScript 5 - Object.definePropertyรองรับใน IE8 +, FF4 +, Opera 12+, WebKit และ Safari นอกจากนี้ยังมี EC5 Shim ที่github.com/kriskowal/es5-shim
Fenton

-1

ใช้ TypeScript 3.4:

interface IPart {
    getQuantity(): number;
}

class Part implements IPart {
    private quantity: number;
    constructor(quantity: number) {
        this.quantity = quantity;
    }
    public getQuantity = (): number => {
        return this.quantity;
    };
}

let part = new Part(42);

// When used in typescript, quantity is not accessible.
// However, when compiled to javascript it will log '42'.
console.log(part.quantity);

// Logs '42'.
console.log(part.getQuantity());

ดูตัวอย่างในtypescript สนามเด็กเล่น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.