禁止添加比界面更多的公共方法

时间:2017-07-27 06:59:03

标签: typescript

interface IHuman {
    talk(): void;
    walk(): void;
}

class Human implements IHuman {
    talk() {
    }

    walk() {
    }

    // This should not be possible:
    fly() {
    }
}

有没有办法告诉编译器只允许添加接口中定义的公共方法?

或者换句话说,在某些情况下禁用鸭子打字?

1 个答案:

答案 0 :(得分:0)

您正在寻找TypeScript目前没有的exact types(截至TS 2.4)。看起来没有立即实施它的计划,因为它可能与类型检查器处理泛型的方式奇怪地相互作用。如果您认为您的用例足够引人注目,则可能需要对the issue in GitHub进行评论。

也许你可以用不同的方式获得你想要的东西?例如,

type Constructor<T> = {
  new (...args: any[]): T;
  readonly prototype: T;
}

// your interface is now a class
class IHuman {
  talk():void {throw new Error("nope")}
  walk():void {throw new Error("sorry")}
  private constructor() {
     // nobody can subclass or instantiate IHuman from outside
  }
  static implement(talkImpl: () => void, walkImpl: () => void): Constructor<IHuman> {
    return class extends IHuman {
      talk() {
        talkImpl();
      } 
      walk() {
        walkImpl();
      }
      constructor() {
        super();
      }
    }
  }
}        

var Human = IHuman.implement(
  () => { console.log('Hello!') }, 
  () => { console.log("I'm walkin', here!") }
);
var human = new Human();
human.talk();
human.walk();

这会强制任何想要获得IHuman子类的人调用IHuman.implement(),这只会允许调用者实现talk()walk()方法。这可能对所有参与者来说都是不愉快的,但它可能是你现在最接近的。