TypeScript简介

TypeScript是由微软开发并开源的一门编程语言。TypeScript被定义为JavaScript的超集,它在JavaScript的基础上增加了静态类型系统和更多的语言特性。TypeScript代码可以被编译为标准的JavaScript代码,因此它可以在任何支持JavaScript的环境中使用,包括浏览器和NodeJS。TypeScript自发布以来迅速获得了广泛的关注和使用,目前已经成为前端开发乃至NodeJS全栈开发中的主流语言之一。
项目主页:https://www.typescriptlang.org/
注意:本系列笔记默认你已经完全熟悉JavaScript,并在此基础之上介绍TypeScript,对JavaScript相关内容不会过多说明,如果你还不了解JavaScript建议先学习相关内容。
TypeScript vs JavaScript
为什么需要TypeScript
JavaScript作为一门动态类型语言,变量的类型是在运行时确定的,这在小型项目中带来了很高的灵活性。然而,随着项目规模的增长,动态类型的弊端就会逐渐显现出来,开发人员可能不小心将错误类型的值赋给变量、调用不存在的方法、传入错误的参数等,而这些错误只有在代码实际运行到对应位置时才会暴露。TypeScript通过引入静态类型系统,使得这类问题可以在编译阶段就被捕获,这大大提升了代码的可靠性和可维护性。除了类型检查,TypeScript还带来了更好的开发体验。由于类型信息的存在,IDE能够提供更加精准的代码补全、跳转定义、重构等功能,这对大型项目的开发效率提升非常明显。
TypeScript和JavaScript的关系
TypeScript被定义为JavaScript的超集,这意味着任何合法的JavaScript代码同时也是合法的TypeScript代码。TypeScript在JavaScript的基础上主要增加了以下内容:
- 静态类型注解:可以为变量、函数参数、返回值等声明类型
- 接口和类型别名:用于描述对象的结构
- 枚举:用于定义一组命名常量
- 泛型:用于编写可复用的类型安全的代码
- 装饰器:用于修饰类和类成员
目前,TypeScript代码无法直接在浏览器或NodeJS中运行,它需要通过TypeScript编译器(tsc)编译为JavaScript代码后才能执行。编译过程中,所有的类型注解都会被擦除,最终输出的仍是纯粹的JavaScript代码,这也意味着不会引入额外运行时开销。
环境搭建
全局安装TypeScript编译器
TypeScript编译器以npm包的形式发布,如果仅用于简单的学习和测试,我们可以通过以下命令进行全局安装。
npm i -g typescript
安装完成后,我们可以使用tsc --version命令来验证是否安装成功。
注意:如果你实在不想全局安装但又想直接使用tsc,那么npx tsc也是可以的。
作为开发依赖安装TypeScript编译器
在实际项目中,我们通常将TypeScript作为项目的开发依赖安装而非全局安装,这样可以确保团队成员使用统一的TypeScript版本。在已经创建好的项目中,执行以下命令局部安装TypeScript编译器。
npm i -D typescript
编写并编译TypeScript代码
下面我们通过一个简单的例子来体验TypeScript的基本用法,我们创建一个hello.ts文件。
const greet = (name: string): string => {
return `Hello, ${name}!`;
};
console.log(greet("TypeScript"));
代码中,我们定义了一个greet()函数,它接收一个string类型的参数name,并返回一个string类型的值。如果我们尝试传入一个非字符串类型的参数,比如greet(123),TypeScript编译器将会在编译阶段报错,而不需要等到代码实际运行时才发现问题。
在命令行中执行以下命令,将TypeScript代码编译为JavaScript代码。
tsc hello.ts
编译后会在同目录下生成一个hello.js文件,我们可以阅读其中的内容,看看TypeScript编译到JavaScript后是什么样子的。最后,我们可以使用NodeJS直接运行这个编译后的JavaScript文件。
node hello.js
tsconfig.json配置文件
tsc编译器有很多配置参数,实际开发中我们不能每次都手动指定这些编译参数,一般来说都要通过tsconfig.json配置文件来管理TypeScript编译器的行为。如果全局安装了tsc编译器,我们可以通过以下命令生成一个默认的配置文件并在其基础上修改。
tsc --init
作为示例,我们这里规划如下的工程目录,它是一个NodeJS工程(如果你的目标是一个浏览器前端项目,配置是不同的,重点关注target、module、lib字段)。
|_ node_modules
|_ src
|_ dist
|_ tsconfig.json
|_ package.json
tsconfig.json
{
"compilerOptions": {
"rootDir": "./src", // 源代码根目录,编译时以此为基准计算输出路径
"outDir": "./dist", // 编译输出目录,`.js`、`.d.ts` 等文件将生成至此
"target": "esnext", // 目标语法版本,`esnext`是个滚动目标,表示使用最新的所有已接近标准化的EcmaScript语法
"module": "nodenext", // 模块系统,这里使用Node原生的ESM模块支持
"lib": ["esnext"], // 注入的JavaScript标准库类型
"declarationMap": true, // 生成`.d.ts.map`文件,用于支持在IDE中“跳转到声明”时定位到原始`.ts`文件
"strict": true, // 启用所有严格类型检查,推荐开启
"esModuleInterop": true, // 兼容CommonJS与ESM互操作
"skipLibCheck": true, // 跳过`node_modules`中`.d.ts`的类型检查,加速编译(第三方类型错误常不可控)
"declaration": true, // 生成.d.ts声明文件,供其他TypeScript项目消费
"sourceMap": true // 生成`.js.map`源码映射文件,便于调试时定位原始TypeScript代码
},
"include": ["src/**/*"], // 显式包含编译范围,仅处理`src`目录及其子目录下所有文件
"exclude": ["node_modules", "dist"] // 显式排除,跳过`node_modules`和`dist`
}
配置完成后,我们还需要安装NodeJS的类型定义包,它里面定义了console、process等全局对象的完整类型定义,不安装可能IDE会提示某些类型找不到的错误。
npm i -D @types/node
上述内容配置好后,我们在项目根目录下直接执行tsc命令即可按照配置文件的规则编译整个项目,无需要逐个指定源文件。tsconfig.json有很多选项,其实还是蛮复杂的,具体使用时可以参考官方文档。
补充说明:实际上,对于NodeJS工程,更一般和推荐的方式是使用ts-node这个包,它可以让我们直接运行TypeScript文件,省去手动tsc编译的麻烦。这部分内容可以参考NodeJS相关章节。至于在前端项目开发中,我们通常也不会直接使用tsc来编译TypeScript代码。现代前端工程大多基于Webpack、Vite等构建工具来进行打包,TypeScript的编译通常由这些构建工具集成的Loader或插件来完成。比如在Webpack中可以使用ts-loader或babel-loader配合@babel/preset-typescript来处理TypeScript文件,在Vite中则内置了对TypeScript的支持,开箱即用。许多前端框架的脚手架工具都提供了TypeScript模板,比如使用Vite创建React项目时,可以直接选择TypeScript模板,并自动生成大部分配置文件。当然,在这些场景下,tsconfig.json依然是必要的,它用于配置IDE的类型检查和代码提示行为,但实际的编译工作则会交由构建工具完成。