TypeScript 接口

摘要: 在本教程中,您将了解 TypeScript 接口以及如何使用它们来执行类型检查。

TypeScript 接口简介

TypeScript 接口定义了代码中的契约。它们还为类型检查提供明确的名称。

让我们从一个简单的例子开始

function getFullName(person: {
    firstName: string;
    lastName: string
}) {
    return `${person.firstName} ${person.lastName}`;
}

let person = {
    firstName: 'John',
    lastName: 'Doe'
};

console.log(getFullName(person));
Code language: TypeScript (typescript)

输出

John DoeCode language: TypeScript (typescript)

在此示例中,TypeScript 编译器会检查您传递给 getFullName() 函数的参数。

如果参数具有两个属性 firstNamelastName,并且它们的类型是字符串,则 TypeScript 编译器会通过检查。否则,它将发出错误。

函数参数的 类型标注 使代码难以阅读。为了解决此问题,TypeScript 引入了接口的概念。

以下使用具有两个字符串属性的接口 Person

interface Person {
    firstName: string;
    lastName: string;
}Code language: CSS (css)

按照惯例,接口名称以 PascalCase 命名。它们使用一个大写字母来分隔名称中的单词。例如,PersonUserProfileFullName

定义 Person 接口后,您可以将其用作类型。例如,您可以使用接口名称来标注函数参数

function getFullName(person: Person) {
    return `${person.firstName} ${person.lastName}`;
}

let john = {
    firstName: 'John',
    lastName: 'Doe'
};

console.log(getFullName(john));Code language: TypeScript (typescript)

现在代码比以前更容易阅读。

为了使代码更简洁,您可以使用 JavaScript 的对象解构功能

function getFullName({ firstName, lastName }: Person) {
  return `${firstName} ${lastName}`;
}Code language: JavaScript (javascript)

在参数中,我们解构了 person 对象的属性

{ firstName, lastName }: Person

getFullName() 函数将接受任何具有至少两个字符串属性(名称为 firstName lastName)的对象。

例如,以下代码声明一个具有四个属性的对象

let jane = {
  firstName: 'Jane',
  middleName: 'K.',
  lastName: 'Doe',
  age: 22,
};Code language: JavaScript (javascript)

由于 jane 对象具有两个字符串属性 firstNamelastName,因此您可以将其传递给 getFullName() 函数,如下所示

let fullName = getFullName(jane);
console.log(fullName); // Jane DoeCode language: JavaScript (javascript)

可选属性

接口可能具有可选属性。要声明一个可选属性,您可以在声明中的属性名称末尾使用问号 (?),如下所示

interface Person {
    firstName: string;
    middleName?: string;
    lastName: string;
}Code language: TypeScript (typescript)

在此示例中,Person 接口具有两个必需属性和一个可选属性。

以下展示了如何在 getFullName() 函数中使用 Person 接口

function getFullName(person: Person) {
    if (person.middleName) {
        return `${person.firstName} ${person.middleName} ${person.lastName}`;
    }
    return `${person.firstName} ${person.lastName}`;
}
Code language: TypeScript (typescript)

只读属性

如果属性只能在对象首次创建时修改,则可以在属性名称之前使用 readonly 关键字

interface Person {
  readonly ssn: string;
  firstName: string;
  lastName: string;
}

let person: Person;
person = {
  ssn: '171-28-0926',
  firstName: 'John',
  lastName: 'Doe',
};
Code language: TypeScript (typescript)

在此示例中,ssn 属性无法更改

person.ssn = '171-28-0000';Code language: TypeScript (typescript)

错误

error TS2540: Cannot assign to 'ssn' because it is a read-only property.Code language: TypeScript (typescript)

函数类型

除了描述具有属性的对象外,接口还允许您表示 函数类型

要描述函数类型,您将接口分配给包含参数列表(带类型和返回类型)的函数签名。例如

interface StringFormat {
    (str: string, isUpper: boolean): string
}Code language: TypeScript (typescript)

现在,您可以使用此函数类型接口。

以下说明如何声明一个函数类型的变量并将其分配给相同类型的函数值

let format: StringFormat;

format = function (str: string, isUpper: boolean) {
    return isUpper ? str.toLocaleUpperCase() : str.toLocaleLowerCase();
};

console.log(format('hi', true));Code language: TypeScript (typescript)

输出

HICode language: TypeScript (typescript)

请注意,参数名称不需要与函数签名匹配。以下示例等效于上面的示例

let format: StringFormat;

format = function (src: string, upper: boolean) {
    return upper ? src.toLocaleUpperCase() : src.toLocaleLowerCase();
};

console.log(format('hi', true));Code language: TypeScript (typescript)

StringFormat 接口确保实现它的函数的所有调用者都传入所需的参数:一个 string 和一个 boolean

以下代码也能完美运行,即使 lowerCase 分配给一个没有第二个参数的函数

let lowerCase: StringFormat;
lowerCase = function (str: string) {
    return str.toLowerCase();
}

console.log(lowerCase('Hi', false));Code language: TypeScript (typescript)

请注意,当调用 lowerCase() 函数时,传递了第二个参数。

类类型

如果您使用过 Java 或 C#,您会发现接口的主要用途是定义类之间的契约。

例如,以下 Json 接口可以由任何类实现

interface Json {
  toJson(): string;
}Code language: PHP (php)

以下声明一个实现 Json 接口的类

class Person implements Json {
  constructor(private firstName: string, private lastName: string) {}
  toJson(): string {
    return JSON.stringify(this);
  }
}Code language: TypeScript (typescript)

Person 类中,我们实现了 Json 接口的 toJson() 方法。

以下示例展示了如何使用 Person

let person = new Person('John', 'Doe');
console.log(person.toJson());Code language: TypeScript (typescript)

输出

{"firstName":"John","lastName":"Doe"}Code language: JSON / JSON with Comments (json)

摘要

  • TypeScript 接口定义了代码中的契约,并为类型检查提供明确的名称。
  • 接口可能具有可选属性或只读属性。
  • 接口可以用作函数类型。
  • 接口通常用作类类型,在不相关的类之间建立契约。
本教程对您有帮助吗?