接口

//js写代码方式 你不知道user对象需要传入什么属性 除非你写注释什么的 注释只起个提示错误却不能提示语法错误 
const getUserInfo = user => {
  return `name:${user.name};age:${user.age}`
}
getUserInfo({}) //
//进化一下 函数调用约束对象传参; 缺点是把函数代码写的过长不方便阅读 这个时候就应该用接口了interface
const getUserInfo1 = (user: { name: string, age: number, }): string => {
  return `name:${user.name};age:${user.age}`
}
getUserInfo1({ name: 'zs', age: 10 })
//下面三种都有错误提示  
// getUserInfo1({name:'zs'})
// getUserInfo1({age:10})
// getUserInfo1({name:'zs',age:10,gender:'male'})
// 再进化一下 用interface约束对象 这个接口也可以重复使用 接口和函数定义参数实现分离

普通接口

直接赋值

 interface IWarningButton {
    class: "warning" //接口属性可以是具体的值
    text1: '修改'
  }
  const warningButton:IWarningButton={class: "warning",text1:'修改'} //但是赋值也是同样的值 不能改为其他值

接口可以嵌套,有更深的子类型

 interface IPerson {
    name: string
    age: number
    job: {
      jobName: string
      place: string
    }
    interests: Array<{ name: string, lever: number }>
  }

函数类型接口 func:interface

第一种:传入一个一个的参数如add(a,b,c)

直接定义一个函数类型接口

// 如果只是简单的传入一个一个的属性给函数 直接就定义一个函数类型接口  这样就直接知道该传什么参数和不该传什么参数
interface ISearchFunc {
  (source: string, substring: string): boolean //形参和实参是根据位置定义的
}
//按照位置对应的 a=>source b=>substring 名字可以相同 ;也可以不同 并且类型都可以省略
const searchFunc1: ISearchFunc = (a, b) => { //这是最简写方式 推荐使用
  return a.includes(b)
}
//最完整写法
const searchFunc2: ISearchFunc = (source: string, substring: string): boolean => {
  return source.includes(substring)
}
searchFunc1('abc','a)
 

第二种,传入一个对象 比如getUserInfo(userObj) 这个时候就需要定义对象接口。函数接口看看自己习惯加不加。最好标准化一点:对象接口+函数接口

对象接口+函数接口

//首先定义一个对象接口
interface IUser1 { //定义一个对象接口
  readonly id: number
  name: string
  age: number

}
// 然后定义一个函数接口 
interface IUserInfoFunc {
  (user: IUser1): string //看这里 这里就使用了接口自定义类型 ts支持的
}
const getUserInfoFunc: IUserInfoFunc = user => {
  return `name:${user.name};id:${user.id};age:${user.age}`
}
getUserInfoFunc({ name: 'zs', age: 10, id: 1000 }) //传入一个对象

只定义对象接口 

interface IUser {
  name: string
  age: number
  gender?: string
  readonly id: number //只读属性 也是必须参数
}
const getUserInfo1 =  (user: IUser): string =>{
  return `name:${user.name};id:${user.id};age:${user.age}`

}

多层对象函数接口:多个对象接口+一个函数接口

//第一个对象接口
interface Item {
  readonly id: number
  name: string
  age?: number
}
// 第二个对象接口
interface ItemList {
  data: Item[]
}
interface IRenderFunc {
  (result: ItemList): void
}
const render: IRenderFunc = result => {
  result.data.forEach(item => {
    console.log(item.id, item.name);
  })
}
let result: ItemList = { //最外面对象
  data: [
    { id: 1, name: 'zs', age: 10 }, //最里面对象
    { id: 2, name: 'lisi' }

  ]
}
render(result)

字面量类型配合接口

字面量类型用来约束取值只能是某几个预定值中的一个。取其他值就会报错

let num=100|200|300
let str="abc"|"aaa"
let aa=100|'100'
//然后引出type定义变量

type EventNames = 'click' | 'scroll' | 'mousemove';

//传入一个request对象
  type method = 'GET' | 'get' | 'POST' | 'post'
  //定义对象接口
  interface IRequestObj {
    url: string
    method: method
  }
  interface IRequestFunc {
    (requestObj: IRequestObj): void
  }
  const request: IRequestFunc = requestObj => {
    console.log(requestObj.url, requestObj.method);
  }
  //use
  request({ url: 'https://www.jianshu.com/p/78b750fb9cd7', method: 'get' })


  // 第二种形式:一个一个传入
  interface IRequestFunc1 {
    (url: string, method: method): void //method 是上面type 定义的method
  }
  const request1: IRequestFunc1 = (url, method) => {
    console.log(url, method);

  }
  request1('https://www.jianshu.com/p/78b750fb9cd7', 'GET')
  
  // 或者这样传 这里的 as const 不是声明变量的关键字,而是 const 类型 ,它会让 const 声明的变量变成真正的字面量类型
  const obj = { url: 'https://www.jianshu.com/', method: 'GET' } as const
  request1(obj.url, obj.method)

总结常见的函数类型接口

 
interface ISearchFunc {
  (source: string, substring: string): boolean //形参和实参是根据位置定义的
}
interface IUserInfoFunc { (user: IUser1): string
//看这里 这里就使用了接口自定义类型 }
interface ICreateSquareFunc { (config: ISquareConfig): { color: string, area: number }
//{ color: string, area: number }返回值也可以定义为一个接口 }
interface ISquareRes { color:string; area:number; } interface ICreateSquareFunc { (config: ISquareConfig): ISquareRes //返回值类型接口 }

类接口 implements

TypeScript也能够用接口来明确的强制一个类去符合某种契约。

 //函数类接口 implements
  interface ISpeakFunc {
    speak: (words: string) => string // 类的实例方法必须严格按照speak定义去实现 包括参数类型、数量和返回值的类型数量
  }
  interface IEatFunc {
    eat: () => void
  }
  class Person implements ISpeakFunc, IEatFunc { //一个类可以有多个接口实现

    speak(a: string) { return 'aa' }
    // speak(a:number){return 'aa'} Error
    // speak(a:string,b: string){return 'aa'} Error
    eat() { }
  }
  const p = new Person()
  p.speak('a')

接口可以继承接口 extends

例子1

 
  //下面这种变量声明不赋值的做法是不允许的 但是ts不会报错
  let square: ISquare //变量声明方式1 ts不会编译报错 但是js之后报错 因为编译为js square默认是undefined undefined是点不出color/penWidth属性的
  square.color = 'red'
  square.penWidth = 10
  square.slideLength = 20

  let square1 = <ISquare>{} //变量声明方式2 这是强制断言 不是泛型
  square1.color = 'blue'
  square1.penWidth = 100
  square1.slideLength = 200

 例子2

 interface ISpeakObj {
    speak: (words: string) => string
  }
  // 接口继承
  interface ISpeakChinese extends ISpeakObj {
    speakChinese: (words: string) => string

  }
  // 对象必须实现speak方法
  const obj: ISpeakChinese = {
    speak: (word): string => { return word }, //这里其实是没有必要再重新申明类型。不能改变 已经定下来了
    speakChinese: (words) => words //这是最好得方式
  }

接口多继承

  interface IFly {
    fly: (location: string) => string //这些通通都是属性接口 和name:string性质是一样的
  }
  interface ISwim {
    swim: (location: string) => string
  }
  interface ISport extends ISwim, IFly { //接口多继承
    jump: (meter: number) => number
  }
  let sport: ISport = { //对象必须得去实现所有接口里面得所有方法
    fly: (a) => a,//这里就不用再给a定义数据类型了 就是string类型,而且还不能改a的数据类型 
    swim(b) { return b }, //也可以用普通函数 但是为了统一和习惯 都用箭头函数
    jump: meter => meter
  }

接口继承type

 type Animal ={
   name:string
   age: number
 }
 interface Dog extends Animal{}
 let dog:Dog = {name:'小辉',age:1}
 

接口继承类

 class Person{
    name:string
    age:number
  }
  

  interface IPerson extends Person{}
  const p1:IPerson={name:'zs',age:18}
原文地址:https://www.cnblogs.com/xiaoliziaaa/p/14930368.html