周末速成 TypeScript
我正在寻找我的第一份开发工作,最近我参加了一家公司的面试,我觉得自己很适合这家公司。然而,职位描述说大部分代码是用 TypeScript 编写的。虽然我已经从其他开发人员那里听说过很多关于 TypeScript 的知识,但我还没有机会开始学习它。我觉得这是一个绝佳的机会,可以一试身手!面试前的一个周末正好有空,所以我决定看看自己能学到多少。在这篇文章中,我将介绍我的发现:TypeScript 的基础知识,以及它相对于 JavaScript 的一些优势。本指南的目标是提供足够的知识,以便进行日常交流,并为在职学习 TypeScript 提供一个良好的起点。
目录
什么是 TypeScript?
TypeScript 是 JavaScript 的超集,可以水平编译回 JavaScript。它提供了强类型 JavaScript 代码等功能。然而,TypeScript 文件实际上无法在浏览器或 Node 中运行。那么,这有什么用呢?
为什么选择 TypeScript?
TypeScript 通过在开发过程中进行类型检查来帮助您避免不必要的运行时错误。TypeScript 文件会被编译成 JavaScript 文件,然后可以在浏览器或 Node.js 中运行。编译器会提前捕获错误,从而节省时间并避免后续调试过程中的挫败感。TypeScript 通过显式定义变量、函数参数和函数输出的类型来提高代码清晰度。这让您一眼就能知道代码应该接收和返回什么,如果您不小心将不该传入的内容传递给函数,编译器会抛出错误。TypeScript 编译器还允许您自定义 TS 文件编译到哪个 JavaScript 版本。这使得开发人员能够使用许多 JavaScript 的新功能,而无需担心浏览器兼容性。因此,TypeScript 还可以提供 JavaScript 中不具备的功能,例如泛型、枚举和接口。此外,TypeScript 在现代 IDE(例如 VS Code)中提供了出色的工具,可以在编写代码时捕获错误,从而节省更多调试时间。
入门
让我们继续深入分析第一段 TypeScript 代码:
const name = 'Shane'
let age = 24
function printNameAndAge(person: string, ageInYears: number): void {
console.log(`${person} is ${ageInYears} years old.`)
}
printNameAndAge(name, age)
现在,你可能会想:“这看起来很像 JavaScript……”。没错,因为它就是 JavaScript!原生 JavaScript 在 TypeScript 中完全有效。所有功能都是可选的,具体如何使用则由开发者决定。当然,这样做并不能让你获得 TypeScript 的任何优势,所以让我们来补充一些:
const name: string = 'Shane'
let age: number = 24
function printNameAndAge(person: string, ageInYears: number): void {
console.log(`${person} is ${ageInYears} years old.`)
}
printNameAndAge(name, age)
如您所见,您可以在变量声明后或函数参数内使用冒号 ( :
) 后跟类型来添加类型注释。void
函数参数后面是函数返回值的类型注释。在本例中,该函数不返回任何内容,因此类型为void
。如果它返回一个字符串,那么我们将其设置string
为 。这使我们能够确保函数始终返回我们想要的内容。
现在我们知道了如何注释类型,让我们深入了解 TypeScript 提供的核心类型。
核心类型
数字
就像 JavaScript 一样,整数和浮点数(小数)之间没有区别,因为所有数字都被视为浮点数。
let luckyNum: number = 13
细绳
字符串(一系列字符)可以使用' '
或表示" "
。您还可以将模板字面量与 一起使用。
let name: string = 'Shane'
布尔值
一个简单的真值或假值。
let isDone: boolean = false
大批
创建数组时,需要将数组类型以及数组内部值的类型标注为数组。可以通过两种方式实现:
let listOfEvens: number[] = [2, 4, 6, 8]
let listOfOdds: Array<number> = [1, 3, 5, 6]
元组
元组允许您创建固定长度的混合类型数组。
let nameAgeArr: [string, number]
nameAgeArr = ['Shane', 24] // ✅
nameAgeArr = [24, 'Shane'] // ❌
枚举
枚举是一种为数值集合赋予更友好名称的方法。例如,如果您有一个对象属性,该属性只能设置为一定数量的选项,则可以将它们标记为数字而不是字符串。这样可以避免拼写、大小写和其他字符串语义上的混淆,同时提高代码的可读性。
enum Genre {
Rock,
Jazz,
Hip-Hop,
}
let giantSteps = {
artist: "John Coltrane",
genre: Genre.Jazz
}
let genreName: string = Genre[0] // will be "Rock"
枚举的数值自动从 0 开始。不过,您可以将第一个值更改为任意数字,余数将从该值开始递增。您也可以手动设置每个值。
enum Genre {
Rock = 3,
Jazz, // => 4
HipHop, // => 5
}
enum Genre {
Rock = 5,
Jazz = 30,
HipHop = 13,
}
任何
any 类型可用于我们尚不知道其值的变量,或者我们不想进行类型检查。这使得 TypeScript 非常灵活,但请谨慎使用,因为它会消除 TypeScript 所赋予的值。
Null 和 Undefined
与 JavaScript 一样,null 和 undefined 也是 TS 中的类型。默认情况下,null 和 undefined 是所有其他类型的子类型,这意味着您可以将 null 或 undefined 赋值给数字类型的变量。
let luckyNumber = 13
luckyNumber = undefined // ✅
绝不
Never 类型表示永远不会发生的值的类型。例如,一个调用时总是抛出错误的函数永远不会返回,因此我们可以将返回类型设置为never
。无限循环的返回类型也可以是never
。
function throwError(msg: string): never {
throw new Error(msg)
}
目的
在 JavaScript 中,所有非原始类型的值都是对象。因此,对象类型表示任何非原始类型的值,或者任何非数字、字符串、布尔值、符号、null 或 undefined 类型的值。
let shane: object
shane = { name: "Shane", age: 24 } // ✅
shane = () => console.log("Hi, my name is Shane") // ✅
shane = "Shane" // ❌
联合类型和别名
如果变量或参数需要更大的灵活性,则可以使用联合类型指定多种类型选项。
let numberOrString: number | string
numberOrString = 13 // ✅
numberOrString = 'thirteen' // ✅
您还可以定义自己的类型,称为别名,以后可以用作类型定义。
type FlexibleNumber = number | string
let luckyNumber: flexibleNumber = 13
luckyNumber = 'thirteen' // ✅
接口
Typescript 允许我们将特定的对象形状定义为一种类型,称为interface
,这使我们能够确保我们使用的对象始终具有正确的键和值类型。
interface Album {
name: string;
artist: string;
numSongs: number;
}
const sgtPepper: Album = {
name: "Sgt. Pepper's Lonely Hearts Club Band",
artist: "John Coltrane",
numSongs: 13
isGood: true // Allowed to have additional properties
}
const help: Album = {
isGood: true // ❌, must contain all properties from interface
}
恭喜!
现在你已经了解了 TypeScript 的基础知识。非常感谢你的阅读,祝你的 TypeScript 之旅一切顺利!