为什么选择 TypeScript

摘要:在本教程中,你将学习为什么应该使用 TypeScript 而不是 JavaScript 来避免动态类型带来的问题。

为什么要使用 TypeScript

使用 TypeScript 主要有两个原因

  • TypeScript 为 JavaScript 添加了类型系统,以帮助你避免 JavaScript 中动态类型带来的许多问题。
  • TypeScript 实现了 JavaScript 的未来特性,也称为 ES Next,因此你今天就可以使用它们。

本教程重点介绍第一个原因。

理解 JavaScript 中的动态类型

JavaScript 是动态类型的。与 Java 或 C# 等静态类型语言不同,值具有类型而不是变量。例如

"Hello"Code language: TypeScript (typescript)

从值可以看出其类型为 string

以下值为数字

2020Code language: TypeScript (typescript)

请看以下示例

let box;
box = "hello";
box = 100;Code language: TypeScript (typescript)

box 变量的类型根据分配给它的值而改变。

要在运行时查找 box 变量的类型,可以使用 typeof 运算符

let box;
console.log(typeof(box)); // undefined

box = "Hello";
console.log(typeof(box)); // string

box = 100;
console.log(typeof(box)); // numberCode language: TypeScript (typescript)

在此示例中,第一条语句定义了一个变量 box 而不赋值。它的类型是 undefined

然后,我们将文字字符串 "Hello" 分配给 box 变量并显示其类型。box 变量的类型更改为 string

最后,我们将 100 分配给 box 变量。这次,box 变量的类型更改为 number

如你所见,一旦分配了值,变量的类型就会发生变化。

而且你无需显式地告诉 JavaScript 类型。JavaScript 会自动根据值推断类型。

动态类型提供了灵活性。但是,它们也会导致问题。

动态类型的问题

假设你有一个函数,它根据 ID 返回一个 product 对象

function getProduct(id){
  return {
    id: id,
    name: `Awesome Gadget ${id}`,
    price: 99.5
  }
}Code language: TypeScript (typescript)

以下使用 getProduct() 函数检索 ID 为 1 的产品并显示其数据

const product = getProduct(1);
console.log(`The product ${product.Name} costs $${product.price}`);Code language: TypeScript (typescript)

输出

The product undefined costs $99.5 Code language: Shell Session (shell)

这不是我们预期的结果。

此代码的问题在于 product 对象没有 Name 属性。它具有 name 属性,第一个字母 n 为小写。

但是,只有在运行脚本后才能知道这一点。

引用对象上不存在的属性是在 JavaScript 中工作时常见的问题。

以下示例定义了一个新的函数,该函数将产品信息输出到控制台

const showProduct = (name, price)  => {
  console.log(`The product ${name} costs $${price}.`);
};Code language: JavaScript (javascript)

以下使用 getProduct()showProduct() 函数

const product = getProduct(1);
showProduct(product.price, product.name);Code language: JavaScript (javascript)

输出

The product 99.5 costs $Awesome Gadget 1 Code language: PHP (php)

这次我们以错误的顺序将参数传递给 showProduct() 函数。这是你在使用 JavaScript 时经常遇到的另一个常见问题。

这就是 TypeScript 发挥作用的原因。

TypeScript 如何解决动态类型问题

要解决引用对象上不存在的属性的问题,请执行以下步骤

首先,使用 接口 定义 product 对象的“形状”。请注意,你将在后面的教程中了解接口

interface Product{
    id: number,
    name: string,
    price: number
};Code language: CSS (css)

其次,显式地使用 Product 类型作为 getProduct() 函数的返回类型

function getProduct(id) : Product{
  return {
    id: id,
    name: `Awesome Gadget ${id}`,
    price: 99.5
  }
}Code language: JavaScript (javascript)

当你引用不存在的属性时,代码编辑器会立即通知你

const product = getProduct(1);
console.log(`The product ${product.Name} costs $${product.price}`);
Code language: JavaScript (javascript)

代码编辑器在 Name 属性上突出显示了以下错误

当你将鼠标光标悬停在错误上时,你会看到一个提示,帮助你解决问题

要解决以错误顺序传递参数的问题,请显式地为函数参数分配类型

const showProduct = (name: string, price:number)  => {
  console.log(`The product ${name} costs $${price}.`);
};Code language: JavaScript (javascript)

当你将错误类型的参数传递给 showProduct() 函数时,你会收到错误

const product = getProduct(1);
showProduct(product.price, product.name);Code language: JavaScript (javascript)

总结

  • JavaScript 是动态类型的,提供了灵活性,但也导致了许多问题。
  • TypeScript 为 JavaScript 添加了一个可选的类型系统来解决这些问题。
本教程是否有帮助?