# 六.接口

前言

接口可以在面向对象编程中表示行为的抽象,也可以描述对象的形状。接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。

# 1.函数接口参数

const fullName = ({
  firstName,
  lastName,
}: {
  firstName: string
  lastName: string
}): string => {
  return firstName + lastName
}
1
2
3
4
5
6
7
8
9

我们可以约束函数中的参数,但是类型无法复用

interface FullName {
  firstName: string
  lastName: string
}
const fullName = ({ firstName, lastName }: FullName): string => {
  return firstName + lastName
}
1
2
3
4
5
6
7

我们可以通过接口进行描述

# 2.函数类型接口

interface FullName {
  firstName: string
  lastName: string
}
interface Fn {
  (obj: FullName): string
}
const fullName: Fn = ({ firstName, lastName }) => {
  return firstName + lastName
}
1
2
3
4
5
6
7
8
9
10

通过接口限制函数的参数类型和返回值类型

# 3.函数混合类型

interface Counter {
  (): number //限制函数类型
  count: 0 //限制函数上的属性
}
let fn: any = () => {
  fn.count++
  return fn.count
}
fn.count = 0
let counter: Counter = fn
console.log(counter())
console.log(counter())
1
2
3
4
5
6
7
8
9
10
11
12

# 4.对象接口

对象接口可以用来描述对象的形状结构

interface Vegetables {
  readonly color: string
  size: string
}
interface Vegetables {
  age?: number
  taste: "sour" | "sweet"
}
const tomato: Vegetables = {
  color: "red",
  size: "10",
  taste: "sour",
}
tomato.color = "green" //仅读属性不能进行修改
1
2
3
4
5
6
7
8
9
10
11
12
13
14

?标识的属性为可选属性,readOnly标识的属性则不能修改。多个同名的接口会自动合并

const tomato: Vegetables = {
  color: "red",
  size: "10",
  taste: "sour",
  type: "蔬菜",
} as Vegetables //多余的属性可以使用类型断言
1
2
3
4
5
6

# 5.任意属性、可索引接口

interface Person {
  name: "string"
  [key: string]: any
}
let p: Person = {
  name: "zhufeng",
  age: 10,
  [Symbol()]: "aaaa",
}
1
2
3
4
5
6
7
8
9

任意属性可以对某一部分必填属性做限制,其余可以随意增减

interface Arr {
  [key: number]: any
}
let p: Arr = {
  0: "1",
  1: "2",
  3: "3",
}
let arr: Arr = [1, "d", "c"]
1
2
3
4
5
6
7
8
9

可索引接口可以用于标识数组

# 6.类接口

这里先来强调一下抽象类和接口的区别,抽象类中可以包含具体方法实现,接口中不能包含实现

interface Speakable {
  name:string,
  speak():void
}
interface ChineseSpeakable {
  speakChinese():void
}
class Speak implements Speakable,ChineseSpeakable{
  name?:string,
  speak(){}
  speakChinese(){}
}
1
2
3
4
5
6
7
8
9
10
11
12

一个类可以实现多个接口,在类中必须实现接口中的方法和属性

# 7.接口继承

interface Speakable {
  speak(): void
}
interface SpeakChinese extends Speakable {
  speakChinese(): void
}
class Speak implements SpeakChinese {
  speakChinese(): void {
    throw new Error("Method not implemented.")
  }
  speak(): void {
    throw new Error("Method not implemented.")
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
vue3.x 源码案例

renderer.ts






 




















...
export interface Renderer<HostElement = RendererElement> {
  render: RootRenderFunction<HostElement>
  createApp:CreateAppFunction<HostElement>
}
export interface HydrationRender extends Renderer<Element | ShadowRoot> { // 接口继承
  hydrate: RootHydrateFunction
}
...
function baseCreateRenderer(
  options: RendererOptions<Node,Element>,
  createHydrationFns:typeof createHydrationFunctions
):HydrationRender
function baseCreateRenderer(
  options: RendererOptions<Node,Element>,
  createHydrationFns:typeof createHydrationFunctions
):any {
  ...
  let hydrate: ReturnType<typeof createHydrationFunctions>[0] | undefined
  let hydrateNode: ReturnType<typeof createHydrationFunctions>[1] | undefined
  return {
    render,
    hydrate
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

hydrations.ts

export function createHydrationFunctions(
  rendererInternals: RendererInternals<Node, Element>
) {
  ...
  const hydrate:RootHydrateFunction = (vnode,container) => {}
  const hydrateNode = (
    node: Node,
    vnode:VNode,
    parentComponent:ComponentInternalInstance | null,
    parentSuspense:SuspenseBoundary | null,
    slotScopeIds: string[] | null,
    optimized = false
  ): Node | null => {
    let nextNode:Node | null = null
    return nextNode
  }
  return [hydrate, hydrateNode] as const
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 8.构造函数类型

interface Type {
  new (name: string): any
}
function createType(target: Type, name: string) {
  return new target(name) // 传入的是一个构造函数
}
class Animal {
  constructor(public name: string) {
    this.name = name
  }
}
let r = createType(Animal, "Tom")
1
2
3
4
5
6
7
8
9
10
11
12

这里无法标识返回值类型

interface Type<T> {
  new (name: string): T
}
function createType<T>(target: Type<T>, name: string): T {
  return new target(name)
}
class Animal {
  constructor(public name: string) {
    this.name = name
  }
}
let r = createType(Animal, "Tom")
1
2
3
4
5
6
7
8
9
10
11
12

new()表示当前是一个构造数类型,这里捎带使用了下泛型。在使用createClass时动态传入类型。