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 添加了一个可选的类型系统来解决这些问题。