TypeScript
接口
我们使用接口来定义对象的类型。接口是对象的状态(属性)和行为(方法)的抽象(描述)
简单理解就是:为我们的代码提供一种约定
我们使用关键字
interface
来声明接口
interface Person {
name: string;
age: number;
}
let tom: Person = {
name: 'Tom',
age: 25
};
我们定义了一个接口
Person
,接着定义了一个变量
tom
,它的类型是
Person
。
这样,我们就约束了
tom
的形状必须和接口
Person
一致。
接口一般首字母大写。(当然挺多人也习惯 I 大写字母开头,用来表示这是一个接口)
函数参数接口
interface FullName{
firstName:string, //必须以分号结束
secondName:string
}
function printName(name:FullName){
// 必须传入对象 对象中包含firstName secondName
console.log(name.firstName+name.secondName)
}
var obj = {
age:20,
firstName:'张',
secondName:'三'
}
printName(obj); // 将实参对象定义在外面 对象中可以有其他属性 但函数中不能使用
printName({firstName:'张',secondName:'三'}); // 对象直接作为实参传入则只能有接口中的属性
函数类型接口
对方法传入的参数 以及返回值进行约束
interface encrypt{
(key:string,value:string):string;
}
const md5:encrypt = function(key:string,value:string):string{
return key+value
}
console.log(md5('name','zhangsan'));
数组类型接口
interface UserArr{
[index:number]:string
}
const arr:UserArr=['arr','bbb']
类类型接口
对类的约束 和抽象类类似
interface Animal{
name:string;
eat(str:string):void;
}
class Dog implements Animal{
name:string;
constructor(name:string){
this.name = name
}
eat(){
console.log(this.name)
}
}
设置接口可选|只读
interface Person {
readonly name: string;
age?: number;
}
可选属性,我们最常见的使用情况是,不确定这个参数是否会传,或者存在。
只读属性用于限制只能在对象刚刚创建的时候修改其值。
此外 TypeScript 还提供了 ReadonlyArray 类型,它与 Array 相似,只是把所有可变方法去掉了,因此可以确保数组创建后再也不能被修改。
索引签名
有时候我们希望一个接口中除了包含必选和可选属性之外,还允许有其他的任意属性,这时我们可以使用 索引签名 的形式来满足上述要求。
需要注意的是,一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集
interface Person {
name: string;
age?: number;
[prop: string]: any; // prop字段必须是 string类型 or number类型。 值是any类型,也就是任意的
}
const p1:Person = { name: "张麻子" };
const p2:Person = { name: "树哥", age: 28 };
const p3:Person = { name: "汤师爷", sex: 1 }
我们规定 以 string 类型的值来索引,索引到的是一个 any 类型的值
接口与类型别名的区别
实际上,在大多数的情况下使用接口类型和类型别名的效果等价,但是在某些特定的场景下这两者还是存在很大区别。
TypeScript 的核心原则之一是对值所具有的结构进行类型检查。
而接口的作用就是为这些类型命名和为你的代码或第三方代码定义数据模型。
type
(类型别名)会给一个类型起个新名字。
type
有时和
interface
很像,但是可以作用于原始值(基本类型),联合类型,元组以及其它任何你需要手写的类型。
起别名不会新建一个类型 – 它创建了一个新名字来引用那个类型。给基本类型起别名通常没什么用,尽管可以做为文档的一种形式使用。
接口和类型别名都可以用来描述对象或函数的类型,只是语法不同
type MyTYpe = {
name: string;
say(): void;
}
interface MyInterface {
name: string;
say(): void;
}
都允许扩展
interface
用
extends
来实现扩展
interface MyInterface {
name: string;
say(): void;
}
interface MyInterface2 extends MyInterface {
sex: string;
}
let person:MyInterface2 = {
name:'树哥',
sex:'男',
say(): void {
console.log("hello 啊,树哥!");
}
}
type
使用
&
实现扩展
type MyType = {
name:string;
say(): void;
}
type MyType2 = MyType & {
sex:string;
}
let value: MyType2 = {
name:'树哥',
sex:'男',
say(): void {
console.log("hello 啊,树哥!");
}
}
不同点
type
可以声明基本数据类型别名/联合类型/元组等,而
interface
不行
// 基本类型别名
type UserName = string;
type UserName = string | number;
// 联合类型
type Animal = Pig | Dog | Cat;
type List = [string, boolean, number];
interface
能够合并声明,而
type
不行
interface Person {
name: string
}
interface Person {
age: number
}
// 此时Person同时具有name和age属性