TypeScript 泛型接口怎么定义和使用?

文章导读
Previous Quiz Next 泛型接口 在 TypeScript 中,泛型接口类似于普通 interface,但它定义了一个或多个类型参数。这些类型参数允许接口在不同数据类型下重用,同时仍强制执行类型安全和一致性。
📋 目录
  1. A 泛型接口
  2. B 泛型接口作为函数类型
A A

TypeScript - 泛型接口



Previous
Quiz
Next

泛型接口

在 TypeScript 中,泛型接口类似于普通 interface,但它定义了一个或多个类型参数。这些类型参数允许接口在不同数据类型下重用,同时仍强制执行类型安全和一致性。

TypeScript 中的 interface 是一种定义对象或 class 结构的方式。它指定了对象或 class 应具有的预期格式,从而确保代码中的一致性和类型安全。

语法

您可以按照以下语法定义泛型接口。

interface IGeneric<T> {
    value1: T;
    value2: T;
}

在上述语法中,'IGeneric' 是一个带类型的 interface,它接受自定义数据类型。在 interface 中,我们将类型 'T' 用作 value1 和 value2 属性的值类型。

示例

在下面的代码中,我们创建了带有自定义类型 'T' 的 'IGeneric' interface。它具有类型为 'T' 的 value1 和 value2 属性。

接下来,我们定义了 IGeneric interface 类型的 'obj' 对象,并使用 number 数据类型作为泛型类型与 interface 结合。随后,我们在输出中打印对象的 'value1' 属性的值。

// 泛型接口
interface IGeneric<T> {
    value1: T;
    value2: T;
}

// 泛型接口的对象
let obj: IGeneric<number> = {
    value1: 10,
    value2: 20
};

console.log(obj.value1);

编译后,将生成以下 JavaScript 代码:

// 泛型接口的对象
let obj = {
    value1: 10,
    value2: 20
};
console.log(obj.value1);

输出

上述示例代码的输出如下:

10

示例

在该代码中,我们在 'IGeneric' interface 中同时使用 'T' 和 'U' 两种数据类型。interface 中的 value1 属性类型为 'T',value2 属性类型为 'U'。

接下来,我们定义了带有 number 和 string 自定义数据类型的 interface 类型的 'obj' 对象。

// 泛型接口
interface IGeneric<T, U> {
    value1: T;
    value2: U;
}

// 使用泛型接口定义对象
let obj: IGeneric<number, string> = {
    value1: 10,
    value2: "Hello"
};

console.log(obj.value2);

编译后,将生成以下 JavaScript 代码:

// 使用泛型接口定义对象
let obj = {
    value1: 10,
    value2: "Hello"
};
console.log(obj.value2);

输出

上述示例代码的输出如下:

Hello

示例

下面的示例与前一个非常相似,但 'IGeneric' interface 包含 merge() 方法,该方法接受类型为 'U' 的参数并返回类型为 'U' 的值。

在定义 'obj' 对象时,我们在 interface 中使用了 number 和 string 数据类型。这意味着 merge() 方法将接受两个 string 参数,并返回 string 值。

在输出中,代码打印了我们作为 merge() 方法参数传递的连接字符串。

// 泛型接口
interface IGeneric<T, U> {
    value1: T;
    // 返回类型为 U 的值的方法
    merge: (a: U, b: U) => U;
}

// 使用泛型接口定义对象
let obj: IGeneric<number, string> = {
    value1: 10,
    merge: (a, b) => a + b
};

console.log(obj.merge("Hello", "world!")); // Hello world!

编译后,将生成以下 JavaScript 代码:

// 使用泛型接口定义对象
let obj = {
    value1: 10,
    merge: (a, b) => a + b
};
console.log(obj.merge("Hello", "world!")); // Hello world!

输出

Helloworld!

泛型接口作为函数类型

开发者也可以将泛型接口用作函数类型。这使您能够在不同类型和场景中使用相同的函数接口,确保类型安全的同时不牺牲灵活性。

示例

在下面的代码中,func_interface 接受泛型类型 T 和 U。它定义了函数的结构,该函数接受类型为 T 的参数并返回类型为 U 的值。

接下来,我们定义了一个返回字符串长度的函数表达式,并将其存储在 stringToLength 变量中。函数表达式的类型使用泛型接口定义,指定为 string 和 number 数据类型。

类似地,我们定义了另一个将数字转换为字符串的函数,其类型为 func_interface,指定 string 和 number 数据类型。

接下来,我们调用这些函数并在控制台打印它们的输出。

// 定义一个用于函数的泛型接口
interface func_interface<T, U> {
    (input: T): U;
}

// 一个匹配 func_interface 接口的具体函数
const stringToLength: func_interface<string, number> = (input) => {
    return input.length;
};

// 使用该函数
const result = stringToLength("Hello, TypeScript!"); // 返回 18
console.log(result);

// 另一个匹配 func_interface 接口的函数
const numberToString: func_interface<number, string> = (input) => {
    return `Number: ${input}`;
};

// 使用第二个函数
const output = numberToString(123); // 返回 "Number: 123"
console.log(output);

编译后,将生成以下 JavaScript 代码:

// 一个匹配 func_interface 接口的具体函数
const stringToLength = (input) => {
    return input.length;
};
// 使用该函数
const result = stringToLength("Hello, TypeScript!"); // 返回 18
console.log(result);
// 另一个匹配 func_interface 接口的函数
const numberToString = (input) => {
    return `Number: ${input}`;
};
// 使用第二个函数
const output = numberToString(123); // 返回 "Number: 123"
console.log(output);

输出

18
Number: 123

简而言之,泛型接口允许开发者使用多种数据类型重用接口。泛型接口可以用作对象或函数类型,从而允许使用具有不同结构的单个函数或对象。