TypeScript——接口

接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约(规范对象的属性 属性的类型 属性值的类型)

可选属性 通过 ? 来设置
只读属性 通过 readonly 来设置
  • 对象类型接口

interface List {
    readonly id: number; // 只读属性
    name: string;
    age?: number; // 可选属性
}

interface Result {
    data: List[]
}

function render(result: Result) {
    result.data.forEach((item) => {
        console.log(item.id, item.name);
    })
}
  • 额外的属性检查:

    可通过一下三种形式,绕过接口因数据字段多余的检查

1. 将数据赋值与变量

let result = {
    data: [
        { id: 1, name: 'A' },
        { id: 2, name: 'B' }
    ]
} 
render(result)

2.类型断言 用 as 或者<>的形式 ,后者在react中使用会出问题

render(<Result>{
  data: [
     { id: 1, name: 'A' },
     { id: 2, name: 'B' }
  ]
} as Result)

3.字符串索引签名

interface List {
    id: number; 
    name: string;
    [x: string]: any; // 用任意的字符串去索引List可以得到任意的结果,这样List就可以支持多个属性了!
}
  • 可索引类型:当不确定接口中属性个数时需要使用索引签名

索引签名包括字符串索引签名和数字索引签名

数字索引接口:

interface StringArray {
    [index: number]: string //用任意数字所以StringArray都会返回一个string 相当于声明了一个字符串类型的数组
}
let chars: StringArray = ['A', 'B']

字符串索引接口:

interface Names {
    [x: string]: string // 此时就不可以声明number类型的成员了-> string[]
    // y: number 会报错,
}
字符串索引签名有两层含义:
1)names 可以有任意多个属性
2)names 可以用字符串索引,既 names['xxx'],或 names.xxx(也可以用数字索引,names[number],数字会被转换成字符串)

可以同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值类型的子类型。(因为JS会对进行类型转换,将number转发为string)

interface Names {
    [x: string]: (string) | (any)
    [y: number]: (string) | (number)
}
  • 函数类型

// 变量形式定义函数
let adds: (x: number, y:number) => number
// 等价于一下接口定义函数
interface Add {
    (x: number, y: number): number
}
// 还可使用 类型别名 的方式定义
type Add1 = (x:number, y: number) => number
let add1: Add1 = (a, b) => a + b

type:不是创建新的类型,只是为一个给定的类型起一个名字。type还可以进行联合、交叉等操作,引用起来更简洁。
interface:创建新的类型,接口之间还可以继承、声明合并。
如果可能,建议优先使用 interface。
  • 混合类型:一个对象可以同时做为函数和对象使用,并带有额外的属性。

一般是为第三方类库写声明文件时会用到,很多类库名称可以直接当函数调用,也可以有些属性和方法。
interface Counter {
    (start: number): string;
    interval: number;
    reset(): void;
}

用混合接口声明函数和用接口声明类的区别是,接口不能声明类的构造函数(既不带名称的函数),但混合接口可以,其他都一样。

  • 类类型

 
implements : 类实现接口时,必须实现接口中声明的所有属性,接口只能约束类的共有成员。
interface Human {
    name: string;
    eat(): void;
}
class Asian implements Human {
    constructor(name: string) {
        this.name = name
    }
    name: string
    eat() {}
    sleep() {}
}
  • 关于继承

接口的继承:可以抽离出可重用的接口 多个接口合并成一个接口 一个接口可以继承多个接口
interface Man extends Human {
    run(): void;
}
interface Child {
    cry(): void;
}
// 可将多个接口封装成一个接口,同样必须事项所有属性
interface Boy extends Man,Child {}
let boy: Boy = {
    name: '',
    eat() {},
    run() {},
    cry() {}
}
接口继承类 :只有类的成员结构 而未具体实现
接口同样会继承到类的private和protected成员。 这意味着当你创建了一个接口继承了一个拥有私有或受保护的成员的类时,这个接口类型只能被这个类或其子类所实现
class Auto {
    statue = 1
}
interface AutoInterface extends Auto {}
class C implements AutoInterface {
    statue = 1
}
class Bus extends Auto implements AutoInterface {}

猜你喜欢

转载自www.cnblogs.com/JessieXie/p/12384876.html