TypeScript 快速入门
TypeScript 快速入门
1. 初识 TypeScript
1.1 TS 是什么?
- 以 JavaScript 为基础构建的语言;
- 一个 JavaScript 的超集;
- 可以在任何支持 JavaScript 的平台执行;
- TypeScript 扩展了 JavaScript 并添加了类型;
- TS 不能被 JS 解析器直接执行(需要先编译为 JS);
1.2 TS 简介
- TypeScript 是 JavaScript 的超集。
- 它对 JS 进行了扩展,向 JS 中引入了类型的概念,并添加了许多新的特性。
- TS 代码需要通过编译器编译为 JS,然后再交由 JS 解析器执行。
- TS 完全兼容 JS,换言之,任何的 JS 代码都可以直接当成 JS 使用。
- 相较于 JS 而言,TS 拥有了静态类型,更加严格的语法,更强大的功能;TS 可以在代码执行前就完成代码的检查,减小了运行时异常的出现的几率;TS 代码可以编译为任意版本的 JS 代码,可有效解决不同 JS 运行环境的兼容问题;同样的功能,TS 的代码量要大于 JS,但由于 TS 的代码结构更加清晰,变量类型更加明确,在后期代码的维护中 TS 却远远胜于 JS。
1.3 TS 增加了什么
- 类型
- 支持 ES 的新特性
- 添加 ES 不具备的新特性
- 丰富的配置选项
- 强大的开发工具
2. TypeScript 开发环境搭建
-
安装 NodeJS
-
全局安装 typescript
npm i typescript -g
-
创建一个 .ts 文件
-
编译
2.1 VScode 编译 ts
-
安装 ts-node
npm i ts-node -g
-
在文件根目录进入终端,运行:
tsc --init
,生成 json 文件 -
在 json 文件中输出路径修改为:
"outDir": "./js/"
; -
终端中运行
tsc -s
,让 VScode 自动监视,也可以使用tsc xxx.ts
单独编译某个 ts 文件。
2.2 给自动编译添加防抖
由于使用 tsc -w
自动编译比较频繁,可以添加一个类似防抖效果,减少不必要的编译
-
安装 chokidar:
npm i chokidar -S
-
在项目根目录下创建一个新文件
watch-and-compile.js
,写入内容const { exec } = require('child_process'); const chokidar = require('chokidar');// 初始化延迟计时器 let timeout;function compile() {console.log('Compiling TypeScript files...');exec('tsc', (err, stdout, stderr) => {if (err) {console.error(`Error: ${stderr}`);} else {console.log(stdout);}}); }// 监听文件变化 const watcher = chokidar.watch('src/**/*.ts', {ignoreInitial: true });watcher.on('all', (event, path) => {console.log(`File ${path} has been ${event}`);// 防抖处理:清除并重新设置计时器if (timeout) clearTimeout(timeout);timeout = setTimeout(compile, 1000); /* 设置时间 */ });console.log('Watching for file changes...');
-
修改
package.json
以增加一个启动脚本{"scripts": {"watch": "node watch-and-compile.js"} }
-
运行以下命令来启动文件变化监听脚本:
npm run watch
。
3. TS 基本类型
3.1 了解 TS 基本类型
-
类型声明
-
类型声明是TS非常重要的一个特点
-
通过类型声明可以指定TS中变量(参数、形参)的类型
-
指定类型后,当为变量赋值时,TS编译器会自动检查值是否符合类型声明,符合则赋值,否则报错
-
简而言之,类型声明给变量设置了类型,使得变量只能存储某种类型的值
-
语法:
let 变量: 类型;let 变量: 类型 = 值;function fn(参数: 类型, 参数: 类型): 类型{... }
-
-
自动类型判断
- TS拥有自动的类型判断机制
- 当对变量的声明和赋值是同时进行的,TS编译器会自动判断变量的类型
- 所以如果你的变量的声明和赋值时同时进行的,可以省略掉类型声明
3.2 基本类型
类型 | 描述 |
---|---|
number | 任意数字 |
string | 任意字符串 |
boolean | 布尔值 |
字面量 | 限制变量的值就是该字面量的值 |
any | 任意类型 |
unknown | 类型安全的 any |
void | 没有值(或 undefined) |
never | 不能是任何值 |
object | 对象 |
array | 数组 |
tuple | 元组,TS新增类型,长度固定的数组 |
enum | 枚举,TS中新增类型 |
-
字面量
也可以使用字面量去指定变量的类型,通过字面量可以确定变量的取值范围
let a: 10; // a = 11; /* 报错,不能将类型“11”分配给类型“10” */let b: 'male' | 'female'; b ='male'; b = 'female';let c: boolean | number; c = true; c = 10;
-
any
可以接收任意类型的值
let d: any; d = 10; d = 'hello'; d = true;
若一个变量设置 any 类型后,相当于关闭了 TS 的类型检查
未声明类型时,变量默认为 any 类型(隐式的 any 类型)
let e;
-
unknown
表示未知类型
let f: unknown; f = 10; f = 'hello';
any、unknown 的区别:
- any 类型的值可以赋值给其它任意类型的值,会影响到其它的值。
- unknown 只能赋值给其他 unknown 类型或 any 类型的值。
unknown 可以看作是安全类型的 any。
-
void
表示空,用在函数中表示没有返回值。
function f(): void {return xxx; /* 报错 */ }
-
never
表示永远不会返回结果
function f(): never {return xxx; /* 报错 */ }
-
object(作用不大)
let g: object; g = {}; g = []; g = function() {};
object 在 TS 中并不实用,因为在 TS 中一切皆对象
-
array
let j: Array<number>; j = [1, 2, 3]; // j = ["1", "2"]; /* 报错,不能将类型“string”分配给类型“number” */let k: string[]; k = ["hello", "world"];
数组两种表示形式:
Array<类型>
或类型[]
。 -
tuple
语法:
变量: [类型1, 类型2]
,类型可以相同,具有个数的限制let l: [string, number]; l = ["hello", 10]; // l = ["hello", "world"]; /* 报错,不能将类型“string”分配给类型“number” */
-
enum
用来定义一组命名的常量值
enum Color {Red,Green,Blue } let m: Color; m = Color.Red; m = Color.Green; m = Color.Blue; // m = Color.yellow; /* 报错,Color 中没有 yellow 属性 */
类型1 | 类型2 ...
表示一个值的类型,满足 类型1 或 类型2;
类型1 & 类型2 ...
表示一个值的类型,满足 类型1 且 类型2,这种表示并没有什么意义,但是可以用在多个值类型的判断,如{参数1: 类型1} & {参数2: 类型2} ..
表示一个对象中 参数1 满足 类型1 且 参数2 满足 类型2;
类型别名:可以给一个类型起一个别名
type Person = {name: string;age: number }; let m: Person; m = {name: "Tom",age: 18 };
3.3 类型断言
类型断言可以用来手动指定一个值的类型,即允许变量从一种类型更改为另一种类型。
语法格式:<类型>值
或 值 as 类型
。
在 TypeScript 中,类型断言(Type Assertion)是一种告诉编译器某个值的具体类型的方法。类型断言有两种常见的语法形式:as
和 !
。
-
as
断言:值 as 类型;
as
断言是 TypeScript 中推荐使用的类型断言语法。它明确地告诉编译器,你确信这个值的类型是什么。- 使用
as
断言时,如果编译器能够推断出这个值可能为null
或undefined
,它不会报错,而是相信你的断言。
-
!
断言:值!;
!
断言(非空断言)是一种更强制的类型断言,它告诉编译器这个值绝对不会是null
或undefined
。- 使用
!
断言时,如果编译器能够推断出这个值可能为null
或undefined
,它会报错,因为!
断言强制排除了这种可能性。
两者的区别:
- 使用
as
断言时,编译器会相信你,认为这个值是你所指定的类型,即使它可能是undefined
。 - 使用
!
断言时,编译器会认为你断言这个值绝对不是undefined
,而实际上它可能是undefined
,可能会报错。
因此,使用 as
断言不会报错,而使用 !
断言会报错,是因为 !
断言强制排除了 undefined
的可能性,而实际上这个值可能是 undefined
。
在 TypeScript 开发中,一般推荐使用
as
断言来进行类型断言。以下是一些原因:
可读性和明确性:
as
断言更加明确和直观,因为它明确地指出了你希望将某个值断言为哪种类型。灵活性:
as
断言允许你在编译器能够推断出值可能为null
或undefined
的情况下,仍然进行类型断言。- 这使得代码更加灵活,因为你可以在不改变编译器行为的情况下,明确地指定类型。
避免过度断言:
!
断言(非空断言)是一种更强制的断言,它告诉编译器这个值绝对不会是null
或undefined
。过度使用!
断言可能会隐藏潜在的空值问题,导致运行时错误。社区惯例:
在 TypeScript 社区中,
as
断言是更常见的做法,因此使用as
断言可以使代码更符合社区惯例,便于他人理解和维护。综上所述,在开发时一般推荐使用
as
断言来进行类型断言,因为它更加明确、灵活,并且符合社区惯例。