停止在 TypeScript 中使用 any 类型
TypeScript 是 Web 开发人员中最常用的编程语言之一。它具有出色的语言功能,允许我们轻松设计可扩展的应用程序。因此,开发人员倾向于在项目中选择 TypeScript 而不是 JavaScript。
然而,在使用 TypeScript 以最大限度地发挥其功能时,我们需要避免一些常见的错误。例如,过度使用 any 类型是我们经常犯的一个常见错误。虽然听起来很简单,但过度使用 any 类型可能完全违反 TypeScript 的基本原理。
因此,在本文中,我们将讨论过度使用 any 类型的问题、any 类型的替代方案以及何时应该和不应该使用 any 类型,以便让我们更好地理解。
TypeScript 中的 any 类型是什么
在 TypeScript 中定义变量时,必须显式告知变量的类型。例如,如果我们使用 string 作为数据类型,TypeScript 会理解该变量只能具有字符串值。如果我们尝试为变量分配不同类型的值,TypeScript 将显示错误。
例如,下面的代码片段会给我们提示 Type ‘number’ is not assignable to type ‘string’ 错误:
let myVariable: string = '';
myVariable = 20;
// error - Type 'number' is not assignable to type 'string'.(2322)
同样,any 是 TypeScript 中另一种可用的数据类型。但它与其他变量不同,因为 any 会告诉 TypeScript 该变量可以具有任何值。因此,如果我们使用 any 类型定义变量,则可以将数字、字符串、布尔值甚至对象分配给该变量,而不会出现错误。
let myVariable: any = 'String Value';
console.log('Value of myVariable : ' + myVariable);
myVariable = 20;
console.log('Value of myVariable : ' + myVariable);
myVariable = false;
console.log('Value of myVariable : ' + myVariable);
有些人可能认为这是定义项目中所有变量的好方法。但使用 any 类型都会带来一些重大缺点,它会使我们的 TypeScript 项目类似于常规 JavaScript 项目。那么,我们来讨论一下为什么我们不应该在 TypeScript 中使用任何类型来定义变量。
为什么我们不应该使用任何类型
类型检查是 TypeScript 最重要的功能之一。通过检查数据分配和类型转换,它有助于避免应用程序中出现意外问题。
当我们使用 any 类型时,变量将没有特定的数据类型,我们可以将多种类型的值分配给同一个变量。此外,编译器不会对 any 类型定义的变量执行类型检查,我们的项目将看起来像一个常规的 JavaScript 项目。
那么,为什么 TypeScript 还提供了一个名为 any 的数据类型。在某些特定情况下,any 类型会显得特别有用。作为开发人员,我们应该能够识别这些情况并相应地应用 any 类型。
我们什么时候应该使用任何类型
如前所述,任何类型的引入都是出于某些特定原因。以下是我们必须使用 any 类型的一些最常见和最重要的情况。
1. 用于迁移
当我们最初将 JavaScript 项目迁移到 TypeScript 时,any 类型是一个很有价值的选项。例如,如果我们要将 AngularJS 项目迁移到新的 Angular 版本,则可以使用 any 类型来处理尚未迁移的变量类型。
2. 匹配三方库
有时,我们可能会遇到 any 类型的第三方库。在这种情况下,我们必须在项目中使用 any 类型才能使用该库。但请确保尽快将它们转换为正确的类型。
3. 处理类型错误
处理 TypeScript 类型错误是我们可能需要 any 类型的另一种情况。如果找不到任何其他解决方案,可以使用 any 类型来解决问题,并稍后将其转换为合适的类型。
有哪些替代 any 的方案
如上所述,any 类型的主要目的是解决开发人员在使用 TypeScript 时可能面临的一些特定场景。然而,开发人员经常面临无法决定变量的特定类型的情况。因此,让我们讨论在这种情况下可以使用的替代方案,而不使用 any 类型。
1.unknown
当我们不知道变量的类型时,使用 unknown 是最好的选择。与 any 不同的是unknown 在确保变量的类型安全时,同时允许我们为变量分配多种类型。
例如,我们可以定义一个具有 unknown 类型的变量,并稍后为其分配任何类型的值:
let myVariable: unknowon = 'unknown type variable';
console.log('Value of myVariable : ' + myVariable);
myVariable = 20;
console.log('Value of myVariable : ' + myVariable);
myVariable = false;
console.log('Value of myVariable : ' + myVariable);
如我们所见,unknown 类型变量与 any 类型变量的工作方式相同。但是,如果我们尝试将它们分配给另一个变量,any 和 unknown 之间是存在差异的。如果我们的变量属于 any 类型,则可以将其分配给另一个变量而不会出现错误。但是,如果我们尝试将 unknown 类型变量分配给具有正确类型的变量,我们将看到错误。
// unknown type
let myVariable1: unknown = 'unknown type variable';
console.log('Value of myVariable1 : ' + myVariable1);
let myVariable2: string = myVariable1;
console.log('Value of myVariable2 : ' + myVariable2);
2. 使用 Interface
对象定义是开发人员使用 any 类型的另一个常见场景,因为它不需要额外的工作。然而,使用 Interface 是处理 TypeScript 中对象类型的最合适的方法。
例如,假设我们需要定义一个名为 article 的对象,该对象具有 title、writer 和views 的属性。如果使用 any 类型,则可以轻松定义对象,如下所示:
const article: any = {
title: 'TypeScript',
writer: 'Chameera',
views: 10000
}
否则,我们可以在定义对象的同时创建 Interface ,如下所示:
// Interface
interface Article {
title: string;
writer: string;
views: number;
}
// Object
const article: Article = {
title: 'TypeScript',
writer: 'Chameera',
views: 10000
}
与 Interface 类似,我们也可以使用类型注释来创建对象类型:
const article: {title: string;writer: string;views: number;
} = {
title: 'TypeScript',writer: 'Chameera'views: 10000
}
使用 unknown 类型和 Interface 是替代 any 类型的最佳选择。这两种方法都是类型安全的,可确保我们不会失去任何 TypeScript 优势。
结论
any 是 TypeScript 中可用的独特数据类型。引入它是为了处理一些独特的场景,例如 JavaScript 到 TypeScript 的迁移。但是,在使用类型之前我们应该三思而后行,因为它会禁用对使用 any 类型定义的变量和对象的类型检查。