Javascript 如何确保扩展类必须在TypeScript中设置属性值?

Javascript 如何确保扩展类必须在TypeScript中设置属性值?,javascript,oop,inheritance,typescript,Javascript,Oop,Inheritance,Typescript,如果我有一个类foo: class Foo { id: number name: string sayHi() { console.log('hi') } } 如何确保从foo扩展的任何类都必须为id和name设置值 class Bar extends Foo { // must set these values id = 1 name = 'bar' } 这个概念或模式有名字吗?我不能将Foo作为接口,因为它必须有继承类可以使用的方法。给Foo一个构造

如果我有一个类
foo

class Foo {
  id: number
  name: string

  sayHi() {
    console.log('hi')
  }
}
如何确保从foo扩展的任何类都必须为
id
name
设置值

class Bar extends Foo {
  // must set these values
  id = 1
  name = 'bar'
}

这个概念或模式有名字吗?我不能将
Foo
作为接口,因为它必须有继承类可以使用的方法。

Foo
一个构造函数,该构造函数需要它们作为参数:

class Foo {
  constructor(public id: number, public name: string) {
    // Validate them here if desired
  }

  sayHi() {
    console.log('hi');
  }
}
由于子类必须(隐式或显式)调用其超类构造函数,因此如果不传入必要的参数而尝试调用,则TypeScript编译器将标记为:
提供的参数与调用目标的任何签名都不匹配。
例如,这两个参数都会失败:

class Bar extends Foo {
}
const b = new Bar();   // Supplied parameters do not match any signature of call target.


注意这里使用的有趣的TypeScript特性:因为我们在构造函数参数上提供了一个访问修饰符,所以在调用构造函数时会自动创建实例属性并将其设置为这些值。这相当于:

class Foo {
  id: number;
  name: string;

  constructor(id: number, name: string) {
    this.id = id;
    this.name = name;
    // Validate them here if desired
  }

  sayHi() {
    console.log('hi');
  }
}
(因为默认修饰符是
public

class Foo {
  id: number;
  name: string;

  constructor(id: number, name: string) {
    this.id = id;
    this.name = name;
    // Validate them here if desired
  }

  sayHi() {
    console.log('hi');
  }
}