跳到主要内容

Why TypeScript

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

为什么使用TypeScript

使用TypeScript有两个主要原因:

  • TypeScript 添加了一个类型系统来帮助你避免 JavaScript 中动态类型的许多问题。
  • TypeScript 实现了 JavaScript 的未来特性,方便今天可以使用它们。

本教程主要讨论第一个原因。

理解 JavaScript 中的动态类型

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

"Hello"

从值中,可以看出它的类型是 string。此外,以下值是一个数字:

2020

请看以下示例:

let box;
box = "hello";
box = 100;

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

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

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

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

box = 100;
console.log(typeof(box)); // number

在本例中,第一条语句定义了变量,但没有赋值。其类型是 undefined

然后,我们将 "Hello" 赋给 box 变量并打印出它的类型。box 变量的类型现在变成了 string

最后,我们给 box 变量赋值 100。这一次,box 变量的类型变成了 number

如你所见,一旦赋值,变量的类型就会改变。

并且你不需要明确地告诉 JavaScript 类型。JavaScript 将自动从值中推断出类型。

动态类型提供了灵活性。然而,它们也带来了问题。

动态类型的问题

假设你有一个基于 id 返回 product 对象的函数:

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

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

const product = getProduct(1);
console.log(`The product ${product.Name} costs $${product.price}`);

输出如下:

The product undefined costs $99.5 

这不是我们期望的结果。

这段代码的问题是 product 对象没有 Name 属性。它的 name 属性的第一个字母 n 是小写的。

但是,只有运行脚本后才能知道。

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

以下示例定义了一个向控制台输出产品信息的新函数:

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

下面使用了 getProduct()showProduct() 函数:

const product = getProduct(1);
showProduct(product.price, product.name);

输出:

The product 99.5 costs $Awesome Gadget 1 

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

这就是 TypeScript 大展身手的原因。

Typescript 如何解决动态类型的问题

要解决引用对象上不存在的属性的问题,需要按照以下步骤:

首先,使用 interface 定义 product 对象。请注意,你将在后面的教程中了解 interface。

interface Product{
id: number,
name: string,
price: number
};

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

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

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

const product = getProduct(1);
console.log(`The product ${product.Name} costs $${product.price}`);

代码编辑器高亮显示了访问 Name 属性时的错误信息:

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

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

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

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

const product = getProduct(1);
showProduct(product.price, product.name);

摘要

  • JavaScript 是动态类型的。它提供了灵活性,但也产生了许多问题。
  • TypeScript 为 JavaScript 添加了一个可选的类型系统来解决这些问题。