使用接口定义一个对象

当我们要在ts中声明一个对象变量,需要提前用接口来声明一个接口类型,然后对这个接口进行赋值,类似于画一个模子,然后填充内容。

  1. interface User {
  2. name: string;
  3. age: number;
  4. }

但是这么做是很不方便的,因为我们这么声明的接口只能接受一摸一样的内容,也就是说由这个接口生成的对象必须有且只有两个属性,即name和age,那么当我们需要后期进行属性的更改和增加要怎么做呢,答案是使用可选属性和任意属性

  1. interface User {
  2. name: string;
  3. age: number;//报错
  4. parent?: string;
  5. [propName: string]: string;
  6. }

上面的属性中,parent是可选属性,代表对象是否有parent属性都可以

[propName: string]是任意属性,事实上propName用任何东西替换都可以,只是表示一个属性的占位符而已,需要注意的是,使用了任意属性,那么这个接口中的所有属性名和属性值的类型都必须和任意属性相同,因此age的number就不符合要求了,当然可以使用联合属性

当我们需要保护一个属性的时候,使用readonly关键字,需要注意的是,readonly在赋值的时候就其效果了,这么说可能有点抽象,举个例子

  1. interface User {
  2. readonly name: string;
  3. age: number;
  4. parent?: string;
  5. [propName: string]: string | number;
  6. }
  7. let jack = {
  8. age: 18,
  9. parent: "mama and baba"
  10. };
  11. jack.name = "jack";//报错

上面这段代码会报错,即使赋值的时候没有name这个属性,但是name属性还是只读的,因此后续给对象增加name属性也是不被允许的。

使用类实现接口

使用类可以实现接口,使用implements关键字,这样类中就必须实现接口中的内容

  1. interface animalAction {
  2. eat(): void;
  3. run(): void;
  4. }
  5. class Animal implements animalAction {
  6. eat() {
  7. console.log("我在吃饭");//少一个都不行
  8. }
  9. run() {
  10. console.log("我在跑");
  11. }
  12. }

使用接口继承接口

可以使用接口继承接口,这和为一个接口声明多次没有本质区别

  1. interface animal1 {
  2. eat(): void;
  3. }
  4. interface animal2 extends animal1 {
  5. run(): void;
  6. }
  7. let dog: animal2 = {
  8. eat() {
  9. console.log("eating");
  10. },
  11. run() {
  12. console.log("running");
  13. }
  14. };//继承写法
  1. interface animal {
  2. eat(): void;
  3. }
  4. interface animal {
  5. run(): void;
  6. }
  7. let dog: animal = {
  8. eat() {
  9. console.log("eating");
  10. },
  11. run() {
  12. console.log("running");
  13. }
  14. };//多次声明
  1. var dog = {
  2. eat: function () {
  3. console.log("eating");
  4. },
  5. run: function () {
  6. console.log("running");
  7. }
  8. };//最终的编译结果是相同的

接口可以继承类

接口可以类继承,实际上,当我们在声明类的时候,除了会创建一个名为类之外,同时也创建了一个实例的类型。就是用这种方法对实例进行约束的。

因此,接口继承类的时候,就是接口继承的实例的类型。

也因此,接口在继承的时候只能继承到实例的方法和属性,即类的是实例方法和实例属性,constructor的内容是继承不到的,因为实例中是不会有的。

接口的合并

可以对同一接口的名字多次声明以扩展一个接口,这经常用于扩展别人的库

  1. interface Alarm {
  2. price: number;
  3. }
  4. interface Alarm {
  5. weight: number;
  6. }
  7. //相当于
  8. interface Alarm {
  9. price: number;
  10. weight: number;
  11. }