二、TypeScript 接口 Interface

2021-11-17  本文已影响0人  輪徊傷

什么是 Interface ?

接口类似于抽象类,只不过他更加彻底,只提供标准却完全不实现细节。具体表现在,成员字段不可以赋值初始化,方法不可以实现。用来约束对象、函数以及类的结构和类型,是一种代码协作必须遵守的契约

可以把它理解为形状,一个对象需要有什么样的属性,函数需要什么参数或返回什么样的值,数组应该是什么样子的,一个类和继承类需要符合什么样的描述等等。

接口的定义

interface Person{
    name: string;
    age: number;
    say(): string;
}

接口的实现

class Man implements Person{
    name: string;
    age: number;
    constructor(name:string, age:number){
        this.name = name;
        this.age = age;
    }
    say(): string{
        return "我的名字是 " + this.name +",今年"+ this.age +"岁了"
    }
}

接口继承接口

interface Person {
    name: string;
    age: number;
    say(): string;
}
//多接口之间逗号分隔
//interface 接口A extends 接口B, 接口C
interface Chinese extends Person{
    run(): string;
}
class Man implements Chinese {
    name: string;
    age: number;
    constructor(name:string, age:number){
        this.name = name;
        this.age = age;
    }
    say(): string{
        return "我的名字是 " + this.name +",今年"+ this.age +"岁了"
    }
    run(): string{
        return "跑步:跑呀跑呀跑呀跑。"
    }
}

接口类型

一、对象 Interface
interface Person {
    name: string
    bool?: boolean
    readonly timeDate: number
    [propName: string]: any
}

let per: Person = {
    name: 'LBipanda',
    bool: true, // 可以设置可选属性 并非必要的 可写可不写
    timeDate: + new Date(), // 设置只读属性
    arr: [1, 2, 3, "name"] // 设置其他额外属性
}

定义的变量比接口少一些或者多一些属性是不被允许的,并且类型要相同
let per1: Person = {
    age: 18, // ❌ 多出来的属性
    name: 123 // ❌ 类型错误
}

per.timestamp = 123 // ❌ 只读属性不可修改
per.arr.pop() // ❌ 只读属性不可修改
二、函数 Interface

Interface 还可以用来规范函数的形状。Interface 里面需要列出参数列表返回值类型的函数定义。写法如下:

1、使用接口定义函数

interface Add {
    (x: number, y: number): number
}
let myFunc: Add = function(x, y){ //es5
  return x+y;
};
let myFunc1: Add = (x, y) =>{ //es6
  return x+y;
};
console.log(myFunc(3,6));
console.log(myFunc(6,4));

三、可索引类型的接口

当不能确定接口中有多少个属性时,可以使用可索引类型接口
可索引类型接口可以用数字去索引,也可以用字符串去索引

一、声明一个数字索引类型的接口:

表示用任意数字去索引numberIndex都会得到一个string
索引值必须为 数字
interface NumberIndex {
    [x: number]: string
}
// 相当于声明了一个字符串类型的数组
let chars: NumberIndex = ['A', 'B']
console.log(chars[1]);

let man: NumberIndex = {
  1: "zhangsan",
  "2": "18"
}
console.log(man[2]);

二、字符串索引接口:

声明一个字符串索引类型的接口:

表示用任意的字符串去索引stringIndex得到的结果都是string
interface StringIndex {
    [x: string]: string
}
这样声明后,就不能声明number类型的成员了,会报错
let obj: StringIndex = {
  name: "LBpanda",
  age: "18",
  height: "178",
  1: 'why'  // 正常编译----字符索引签名类型包含一部分数字索引签名类型
}

console.log(obj.name);
interface StringIndex {
    [x: string]: string
    y: number;// Property 'y' of type 'number' is not assignable to string index type 'string'.
}

三、两种索引签名混用:

interface Indexes {
  [x: string]: string 
  [z: number]: string
}

这样做,接口既可以用数字索引Names,也可以用字符串索引Names

let obj: Indexes = {
  name: "LBipnada",
  1: "18"
}

注意: 数字索引的注解类型,一定要是字符串索引的注解类型或者是子类型

这是因为JS会进行类型转换,将 number 转换成 string ,这样就能保证类型的兼容性

interface Indexes {
  [x: string]: string | number     数字索引的注解类型和字符串索引的注解类型相同
  // [x: string]: any    数字索引的注解类型,是字符串索引的注解类型的子类型
  [z: number]: number
}

let obj: Indexes = {
  name: "LBipnada",
  1: 18
}

四、混合类型的接口

什么是混合类型:函数类型的interface,通过添加属性的方式来实现对象的interface;

interface Counter {
  (start: number): void // 1️⃣ 如果只有这一个那么这个接口是函数接口
  add(): void // 2️⃣ 这里还有一个方法,那么这个接口就是混合接口
  log(): number // 3️⃣ 这里还有另一个方法
}

function getCounter(): Counter { // ⚠️ 它返回的函数必须符合接口的三点
  let count = 0
  //function counter (start: number) { count = start } // counter 方法函数
 let counter = <Counter>function counter (start: number) { count = start } // counter 方法函数
  counter.add = function() { count++ } // add 方法增加 count
  counter.log = function() { return count } // log 方法打印 count
  return counter
}

const c = getCounter()
c(10) // count 默认为 10
c.add()
console.log(c.log())
上一篇下一篇

猜你喜欢

热点阅读