Skip to content

接口类型

在 TypeScript 中,接口(interface)用于定义对象的形状(即结构)。它们可以描述对象的属性、方法签名以及函数类型等。接口是实现面向对象编程中的鸭子类型检查(duck typing)的一种方式,意味着如果一个对象“看起来像”某个接口,那么它就可以被视为实现了该接口。

定义接口

要定义一个接口,使用 interface 关键字,后跟接口名称和花括号 {},其中包含接口成员的声明:

typescript
interface LabelledValue {
  label: string;
}

function printLabel(labelledObj: LabelledValue) {
  console.log(labelledObj.label);
}

let myObj = { size: 10, label: "Size 10 Object" };
printLabel(myObj); // 输出: Size 10 Object

在这个例子中,LabelledValue 接口规定了任何传递给 printLabel 函数的对象都必须有一个名为 label 的字符串属性。

可选属性

接口还可以包含可选属性,通过在属性名后面添加 ? 来标记:

typescript
interface SquareConfig {
  color?: string;
  width?: number;
}

只读属性

只读属性只能在对象创建时赋值,之后不能修改。使用 readonly 关键字来定义:

typescript
interface Point {
  readonly x: number;
  readonly y: number;
}

let p1: Point = { x: 10, y: 20 };
// p1.x = 5; // 错误! 不能对只读属性 'x' 赋值

额外属性检查

默认情况下,TypeScript 会检查对象是否有多余或未定义的属性。你可以使用索引签名或者类型断言来绕过这些检查:

typescript
interface SquareConfig {
  color?: string;
  width?: number;
  [propName: string]: any; // 允许额外的任意属性
}

// 或者使用类型断言
let squareOptions = { colour: "red", width: 100 } as SquareConfig;

函数类型接口

接口也可以用来定义函数的类型,包括参数列表和返回值类型:

typescript
interface SearchFunc {
  (source: string, subString: string): boolean;
}

let mySearch: SearchFunc;
mySearch = function (source: string, subString: string) {
  return source.search(subString) !== -1;
};

可索引类型接口

对于那些可以通过索引访问的数据结构(如数组或映射),你可以定义索引签名:

typescript
interface StringArray {
  [index: number]: string;
}

let myArray: StringArray;
myArray = ["Bob", "Fred"];

let myStr: string = myArray[0];

继承接口

一个接口可以从另一个接口继承,这允许你基于现有接口创建新的接口:

typescript
interface Shape {
  color: string;
}

interface Square extends Shape {
  sideLength: number;
}

let square = <Square>{};
square.color = "blue";
square.sideLength = 10;

混合类型接口

有时你可能想要一个接口既表示一个对象又有函数调用的能力。这称为混合类型接口:

typescript
interface Counter {
  (start: number): string;
  interval: number;
  reset(): void;
}

function getCounter(): Counter {
  let counter = <Counter>function (start: number) {};
  counter.interval = 123;
  counter.reset = function () {};
  return counter;
}

let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;

接口扩展

除了从其他接口继承,TypeScript 接口还可以扩展类,从而获取类的所有公共成员:

typescript
class Control {
  private state: any;
}

interface SelectableControl extends Control {
  select(): void;
}

class Button extends Control implements SelectableControl {
  select() {}
}

class TextBox extends Control {
  select() {}
}

// Error: Property 'state' is missing in type 'Image'.
class Image implements SelectableControl {
  select() {}
}

以上就是 TypeScript 中接口类型的概述及其常见用途。接口提供了一种强大的机制来确保对象遵循特定的结构,有助于编写更加健壮和易于维护的代码。

Released under the MIT License.