注意: 如果您是 TypeScript 新手,请先查看我们的 TypeScript 入门 教程。
在 TypeScript 中,接口是一种定义对象形状的方式。
这是一个简单的接口示例。您可以阅读本教程的其余部分以了解更多信息。
示例
interface Person {
name: string;
age: number;
}
const person: Person = {
name: "Alice",
age: 30,
};
console.log(person);
// Output: { name: 'Alice', age: 30 }
在这里,Person
接口定义了一个 Person
对象应该有一个 name
(字符串)和一个 age
(数字)。
TypeScript 接口的语法
接口使用 interface
关键字定义,后跟接口名称和一组属性(带类型)。
interface InterfaceName {
property1: type;
property2: type;
// More properties...
}
接口只是一个用于塑造值的契约,它们本身不包含实际值。
实际值在我们根据该接口类型创建对象时分配。让我们看一个例子。
示例 1:汽车接口
让我们定义一个名为 Car
的接口,它描述了汽车对象的结构。
// Define an interface named Car
interface Car {
brand: string;
model: string;
year: number;
}
// Create a Car object
const car: Car = {
brand: "Tesla",
model: "Model 3",
year: 2022,
};
console.log(car);
输出
{ brand: 'Tesla', model: 'Model 3', year: 2022 }
Car
接口定义了汽车对象的结构,指定它应该具有 brand
、model
和 year
属性。
然后,我们创建了一个 Car
类型的 car
对象,并为其 brand
、model
和 year
分配了实际值。
带有可选属性的接口
接口中的某些属性可能并非始终可用。为了处理这种情况,TypeScript 允许您通过在属性名后添加 ?
来定义可选属性。例如,
interface Car {
brand: string;
model: string;
color?: string; // Optional property
}
let myCar: Car = { brand: "Toyota", model: "Corolla" };
let anotherCar: Car = { brand: "Honda", model: "Civic", color: "Red" };
console.log(myCar);
console.log(anotherCar);
输出
{ brand: 'Toyota', model: 'Corolla' } { brand: 'Honda', model: 'Civic', color: 'Red' }
在这里,我们添加了 color
属性,它是可选的(由 ?
表示),这意味着对象可以包含或省略它。
myCar
对象不包含 color
,而 anotherCar
对象包含。
常见问题
readonly
属性只能分配一次,通常是在对象初始化期间。之后,其值不能被修改。例如,
// Define a Rectangle interface with read-only properties
interface Rectangle {
readonly width: number;
readonly height: number;
}
// Create a Rectangle object
let myRectangle: Rectangle = { width: 20, height: 30 };
// Error: Cannot assign to 'width' because it is a read-only property
myRectangle.width = 25;
在这里,Rectangle
将 width
和 height
定义为 readonly
属性。一旦创建了 myRectangle
对象,width
和 height
的值就不能被更改。
函数类型的接口
您还可以使用接口来定义函数的结构,指定参数和返回类型。例如,
interface Greet {
(name: string): string;
}
const greet: Greet = (name) => `Hello, ${name}!`;
// Call the greet() function and log the result
console.log(greet("Selena"));
输出
Hello, Selena!
这里,
interface Greet { (name: string): string; }
创建了一个函数的蓝图。它说明 Greet
函数应该接受一个 name
(字符串)作为参数并返回一个 string
。
然后,我们创建一个实际的 greet()
函数来匹配该蓝图
const greet: Greet = (name) => `Hello, ${name}!`
greet()
函数接受一个 name
并返回一个问候消息(例如,Hello, Selena!
)。
TypeScript 类中的接口
在 TypeScript 中,接口还用于定义类必须遵循的结构。
接口可以指定类应具有的属性和方法,并且类实现该接口以确保它遵循所需的结构。
例如,
// Define an interface for animals
interface Animal {
name: string;
sound: string;
makeSound(): void;
}
// Dog class implements the Animal interface
class Dog implements Animal {
name: string;
sound: string;
constructor(name: string, sound: string) {
this.name = name;
this.sound = sound;
}
makeSound() {
console.log(`${this.name} says: ${this.sound}`);
}
}
// Create a Dog object and call makeSound()
let dog = new Dog("Buddy", "Woof");
dog.makeSound();
// Output: Buddy says: Woof
首先,我们定义了 Animal
接口,它具有
name
和sound
(均为string
)属性makeSound()
方法,返回void
然后,我们定义了实现 Animal
接口的 Dog
类。这意味着 Dog
类必须包含 name
、sound
属性和 makeSound()
方法,正如 Animal
接口所要求的。
接口在测试中的用例
接口在测试场景中特别有用。例如,在支付系统中,您可以定义一个 IPayment
接口,概述必要的属性和方法。
// Define a payment interface with an amount and a method
interface IPayment {
amount: number;
processPayment(): string;
}
// Implement the IPayment interface in a class
class TestPayment implements IPayment {
amount: number;
constructor(amount: number) {
this.amount = amount;
}
processPayment() {
return `Payment of $${this.amount} processed in test mode.`;
}
}
// Create an instance and call the method
const testPayment = new TestPayment(100);
console.log(testPayment.processPayment());
输出
Payment of $100 processed in test mode.
在测试中,TestPayment
类模拟了支付行为。通过实现 IPayment
接口,它确保与实际支付类的一致性,从而减少错误并提高可靠性。
这种方法保证了测试类遵循与生产类相同的契约,从而确保系统在实际和测试场景中都能正确工作。
另请阅读