介绍
TypeScript 是 JS 的严格超集,也就是说 JS 有的他都有,并且为我们新增了严格的静态类型检查还有现代化语言的一些特性。如果你学过 Java 这种强类型语言,那么 TypeScript 可以很快上手。
安装 & 环境初始化
首先我们需要安装 TypeScript
npm i typescript -g
然后开始构建一个项目
mkdir ts-study
cd ts-study
npm init
npm i lite-server --save-dev
接下来我们先创建一个 index.html 文件和 index.ts 文件,并且在 HTML 文件中引入 index.js,然后修改代码
// package.json 中在 scripts 中增加
"start": "lite-server"
// 在命令行中执行 tsc -init 创建 TS 配置文件
// 执行 npm run start
// 在 index.ts 输入以下代码
console.log('Hello world');
// 在命令行中执行 tsc -w 每次 ts 文件保存都会自动编译
// 然后在打开的网页中你应该可以看到 log 的 Hello world
到这一步,我们的 TS 环境已经跑起来了,如有问题请仔细核对步骤。接下来让我们先来学习 TS 的类型。
类型
接下来我们的代码都会写在 index.ts 中
Number & Bool
先让我们来看 number 类型
// 这个代码和我们的 JS 看起来没任何区别
// 但是在 TS 中只要你这样给变量赋值了
// 就代表接下来这个变量只能为 number 类型
let n = 1
n = '1' // => 会报错
// 以上赋值的代码,其实就等于
let n: number = 1
// 但是如果你用上面的方式写代码,就叫做显式声明类型
// 第一句代码是隐式声明类型
n = 2.5
// 不会报错,因为在 TS 中 number 类型为浮点型
接下来学习 bool 类型
let isDay = true
// 在 JS 中,除了 true,像很多对象或者 1 都可以代表 true
// 但是在 TS 中,布尔值就是布尔值,只有 true 和 false
isDay = 1 // 报错
数组 & 元组
先说数组,数组在 TS 中没什么变化
let arr = [1]
// 在定义一个数组类型变量的时候
// 我推荐使用显式声明类型的方式
// 因为数组中你不一定都会存储同一类型
// 例如以上代码,如果你想添加一个别的类型元素
// 就会报错,因为
let arr: number[] = [1]
// 如果你想该变量还可以存储字符串的话
let arr: (number | string)[] = [1]
arr.push('1')
再来讲讲元组。元组对于 JS 来说是个全新的类型,在这里你可以把它看做是一个固定顺序声明类型的数组,这个有点不大好理解,代码说明。
let tuple: [string, number] = [1] //error
let tuple: [string, number] = ['1'] //error
let tuple: [string, number] = [1, '1'] //error
let tuple: [string, number] = ['1', 1] //success
let tuple: [string, number] = ['1', 1, 1] //success
let tuple: [string, number] = ['1', 1, true] //error
// 从以上代码得出,元组显式声明了什么类型和长度
// 那么你元组相应的也必须是这个类型和大于等于该长度
枚举
这也是 JS 没有的类型,这个类型通常来说是为了解决魔法数字的痛点。
enum ServerCode {
notFound = 404,
success = 200
}
let code = ServerCode.success;
console.log(code);
switch (404) {
case ServerCode.notFound:
console.log("404");
break;
case ServerCode.success:
console.log("200");
break;
default:
break;
}
对于枚举来说,如果你不给 notFound
赋值,那么 notFound
就是 0,接下来以此类推加一。
如果你给notFound
赋值为1,其他的类型都不赋值,那么第二个类型值就为 2,接下来以此类推加一。当然你可以还会遇到这种情况
enum ServerCode {
notFound = 404,
success = 200,
a, // 201
b = 300,
c // 301
}
Any
这个类型基本不推荐在 TS 中使用,因为你一旦使用该类型,就少了 TS 的一大利器静态检查了。
// 一旦你这样声明变量,就会隐式声明为 any
let any
any = 1
any = true
函数
当然了,函数也是个类型
function hello(): void {
console.log('Hello'); // error
// void 只能返回 undefined
// 声明了什么类型就得返回什么类型
return '1'
}
// 对于函数来说,一般推荐参数声明类型
// 返回值会自动推断类型,不需要声明
// 当然你想写必然也是没毛病的
function sum(a: number, b: number) {
return a + b
}
// 当然了,如果你希望声明一个函数类型变量
let fun: (a: number, b: number) => number
// 当然以后只能这样赋值了
fun = sum // success
fun = hello // error
// 现在又有个需求,我需要声明10个这样类型的变量
let fun1: (a: number, b: number) => number
let fun2: (a: number, b: number) => number
let fun3: (a: number, b: number) => number
....
// 这样写类型就太累了,我们可以给类型取个别名
type sumType = (a: number, b: number) => number
// 然后你就可以这样写了
let fun1: sumTyp
Never
这是个 TS 2.0 时候加的新类型
function hello(): never {
throw Error('111')
}
// never 返回值类型指的是
// 永远不会执行完的函数或者没有返回值的函数
// 那么你可以觉得如下代码是返回 never 类型
function hello1(): never {
console.log('Hello'); //error
}
// 因为该代码他还是返回了 undefined
所以,如果你在想 Never 和 void 有什么区别的话。区别就是 void 代表返回 undefined,Never 代表函数不会执行完成,也不会返回任何值。
Non-Nullable
这也是 2.0 新增的一个类型,当然了,这个类型我们是声明不出来的。
还记得我们最开始生成的 tsconfig.json
文件不,你可以在该文件下找到 strictNullChecks
这个属性。这个属性默认值是 false, 这个属性的意思是说我们之前讲的那些类型,你都可以将他们赋值为 null 或者 undefined(除了 void),如果你将 strictNullChecks
设为 true,那么你就不可以将他们设置为 null 或者 undefined,除非你这样声明类型。