TypeScript 泛型与类型约束 | 提升代码灵活性与安全性

109 阅读3分钟

课程链接深入浅出 TypeScript - 掘金

TypeScript文档TypeScript: JavaScript With Syntax For Types.


首先先介绍TypeScript的泛型与类型约束,之后再对比它与JavaScript的差异

泛型与类型约束

统一数据类型,避免重复代码

下面的identity函数用于返回输入的值。如果没使用泛型,那就要给数字、字符串、布尔值各写一个函数。

function identity<T>(value: T): T {
    return value;
}

TypeScript会根据输入的类型自动匹配,可以传 identity<number>(42),也可以 identity<string>("Hello")

处理多种数据结构

getArrayLength 函数用于统计数组的长度。用泛型的话,这个函数就能处理各种类型的数组——整型数组、字符串数组,对象数组

function getArrayLength<T>(arr: T[]): number {
    return arr.length;
}

T[] 表示任何类型的数组,比如[1, 2, 3]["a", "b", "c"],都能放进去,TypeScript自动适配

使用类型约束,让泛型更精准

extends 来限制泛型的类型。比如,定义一个 printLength 函数,用于打印输入的数据长度,要求输入的内容必须有 length 属性

function printLength<T extends { length: number }>(value: T): void {
    console.log(value.length);
}

只有带 length 属性的类型才能作为参数传进来,比如 stringarrayobject,而 number 就不行。

类型约束的细化

function printNonEmptyLength<T extends { length: number }>(value: T): void {
    if (value.length > 0) {
        console.log(value.length);
    } else {
        console.log("传入的值不能为空!");
    }
}

不光是 length 属性,还可以加一个“内容不能为空”的规则。要求传入的数组、字符串,必须是非空的。

TypeScript与JavaScript的差异

项目对比:数字数组求和

写一个函数,接受一个数字数组,返回数组中的数字和。

JavaScript 版本

function sum(numbers) {
    return numbers.reduce((total, num) => total + num, 0);
}

const result = sum([1, 2, 3, 4, 5]);
console.log(result);  

image.png

sum 函数没有任何类型声明,numbers 参数可以接受任何类型的数据。如果传入了不符合要求的类型,比如传入字符串或布尔值,JavaScript 也不会报错,只是在运行时出错,导致结果不对。

image.png

JavaScript并没有静态类型检查的机制,也没有泛型这类功能。

TypeScript 版本

numbers: number[] 它强制要求 numbers 参数必须是一个包含数字的数组,而返回值的类型也是 number。如果传入一个非数字类型的数组,TypeScript 会在编译时报错。开发时能更早发现潜在的错误,避免了运行时的麻烦。

function sum(numbers: number[]): number {
    return numbers.reduce((total, num) => total + num, 0);
}

// 使用这个函数
const result = sum([1, 2, 3, 4, 5]);
console.log(result);  // 输出 15

在线编译TypeScript: 演练场 - 一个用于 TypeScript 和 JavaScript 的在线编辑器

image.png

在运行之前,可以看到错误显示~

总结

此文章探讨了 TypeScript 中泛型的使用方法及其在不同场景中的应用。

通过引入泛型,TypeScript 让代码可以适应多种数据类型,避免重复代码,提升了复用性。

同时,使用类型约束可以进一步精确控制泛型的适用范围,确保代码在灵活性和类型安全性之间找到平衡。

通过对比 JavaScript 和 TypeScript 的实现,发现JavaScript 代码更灵活,但缺乏类型检查,容易引入潜在错误;而 TypeScript 则通过泛型和类型约束,为代码提供了静态检查能力,降低了运行时错误的风险,更适合大型项目和团队协作。