接口(interface)
接口可以用来描述一个具体的对象、描述函数类型或者描述类的类型
-
描述一个具体的对象
interface IOption { label: string; value: number; } let obj: IOption = { label: "key", value: 1, }; -
描述函数类型
interface userInfoFunc { ( age: number, name: string ) : string } let exampleFuncOne: userInfoFunc = function (age: number, name: string) { return `${name}今年${age}岁了` } let exampleFuncTwo: userInfoFunc = (year: number, monicker: string) => { return `${monicker}今年${year}岁了` } -
描述类类型,使用 implements 实现接口
interface IAnimal { name: string; age: number; } class Panda implements IAnimal { name = "mike"; age = 18; } -
描述构造函数
interface People { run: () => void; } interface PeopleConstructor { new (name: string): People; } class Student implements People { constructor(name: string) {} run() { console.log("run"); } } function createPeople(construction: PeopleConstructor, name: string): People { return new construction(name); } let stu = createPeople(Student, "小明");
接口的属性
-
可选属性
在可选属性名字定义的后面加一个
?符号,表示该属性“可有可无”interface IOption { label?: string; value: number; } let obj: IOption = { value: 1, }; -
只读属性
在只读属性名字定义的前面加上关键词 readonly,表示该属性赋值后不可再改变
interface IUser { readonly name: string readonly age: number } let myUser: IUser = { name: 'mike', age: 18 } myUser.age = 20 // error
可索引的类型
可索引类型具有一个 索引签名,它描述了对象索引的类型,还有相应的索引返回值类型。
interface StringArray {
[index: number]: string;
}
let nameArray:StringArray = ['mike', 'jack'] // ok
let numArray:StringArray = [1,2] // error
如上:StringArray的索引签名表示,当使用 number类型 索引时会得到 string类型
Typescript 支持 number 和 string 两种索引签名
两种可以同时使用,但是,由于使用 number 索引时,js 默认会将其转化为 string 再去索引对象,比如 100 (number)的索引等同于使用 ”100“ (string)去索引。
let obj = {
100 : 'digital'
}
console.log(obj[100] === obj["100"]) // true
所以,数字索引的返回值必须是字符串索引返回值类型的子类型。
class Animal {
name: string;
}
class Dog extends Animal {
breed: string;
}
interface NotOkay {
[x: number]: Animal;
[x: string]: Dog;
} // error
interface Okay {
[x: number]: Dog;
[x: string]: Animal;
} // ok
字符串的索引签名会让所有属性与其返回值类型相匹配。
interface StringIndexSign {
quantity: 20; // error
visible: true; // error
name: 'jack'; // ok
10: 0; // error
11: ''; // ok
[x: string]: string;
}
接口继承
和类一样,接口也可以相互继承。
interface People {
name: string;
}
interface China extends People {
language: string
}
interface Usa extends People {
skinColor: string
}
interface HalfBlood extends China, Usa{ // 也可以继承多个
weight: number
}
let Jessie:HalfBlood = {
name: 'Jessie',
language: 'Chinese',
skinColor: 'yellow',
weight: 50,
}
接口声明合并
同名的接口会把各自的成员合并到一起
interface people {
name: string
}
interface people {
age: number
}
const p1: people = {
name: 'mike',
age:18
}
如果两个接口中同时声明了同名的非函数成员且它们的类型不同,则编译器会报错。
interface people {
height: string
}
interface people {
height: number // error
}
对于函数成员,每个同名函数声明都会被当成这个函数的一个重载。
类型别名 type
可以借助 type 给类型起一个新名字。这里 type 只是创建一个新名字来引用那个类型,并不会新建一个类型。
type myString = string
let userName: myString = ''
type stringOrNumber = string | number
let myVariable = 1
interface people {
name: string
}
type myPeople = people
interface 和 type
interface 和 type 可以描述一个对象或者函数,
type 可以声明基本类型别名,联合类型,元组等类型等等,interface不行
interface 支持声明合并,可以被 extends 和 implements,type 不支持