TS是JS的超集。相比于JS,TS增加了数据类型校验,让开发变得更严谨,能够帮助开发人员检测出错误并修改,提高了代码的可读性,使维护或重构代码都更加容易。
1. 搭建ts环境
安装typescript:
npm install -g typescript
安装完成后,我们可以通过 tsc -v命令来查看typescript的版本号:
tsc -v
新建一个test.ts文件 ,并书写代码:
如:console.log('hello ts')
通过tsc test.ts命令将Typescript转换为Javascript代码,没有报错便编译成功
报错:如果报错tsc:无法加载文件,可以以管理员身份打开Powershell,执行set-ExecutionPolicy RemoteSigned命令
set-ExecutionPolicy RemoteSigned
将执行策略更改为RemoteSigned,在询问更改执行策略时选择Y或A,更改完成后重新打开vscode或终端再次执行编译命令既可:
运行后会自动在.ts文件同一目录下会生成相应文件名的.js文件
使用node命令执行该js文件,即可运行代码
每次手动编译很麻烦,也可以使用ts-node包,或者vscode编译器的tsconfig.json文件,有兴趣的童鞋可以去查一下。
2.TypeScript基础内容
TS类型包含了JS的所有基础类型(Boolean、Number、String、null、undefined,包括ES6的Symbol以及ES10的BigInt)
除此之外,TS还增加了void(空值)、any(任意)、unknown(未知)、never(没有值)、tuple(元组)、enum(枚举)等等
1)Boolean类型
布尔类型的变量只接受true或false
let flag: boolean = true
// 可以将Boolean()函数转换的结果赋值给布尔类型的变量
// 但不可以将构造函数Boolean的实例化赋值给boolean类型的变量,因为构造函数的实例并不是一个布尔值
flag = Boolean(1)
// 将参数‘1’转换为布尔值且返回
flag = new Boolean(1) // 报错
// 将参数‘1’转换为布尔值,且返回一个包含该值的Boolean对象
2)Number类型
数字类型接受整型和浮点型,并支持二、八、十、十六进制以及NaN
let num: number = 10 // 整型
num = 1.00001 // 浮点型
num = Infinity // 无穷大
num = -Infinity // 无穷小
num = 6 // 十进制
num = 0x000a // 十六进制
num = 0b1010 // 二进制
num = 0o777 // 八进制
num = NaN // 不是一个合法的数字
3)String类型
字符串类型接受所有字符串包括字符串模板
let str: string = '123' // 普通字符串声明
str = `456${str}` // 字符串模板声明
4)null和undefined类型
// undefined 类型的变量只能被赋值为 undefined,null 类型的变量只能被赋值为 null
let u: undefined = undefined
let n: null = null
5)void类型
声明为void 类型的变量,只能赋予undefined或者null(只在 --strictNullChecks 未指定时)
这句话是在TS文档中找到的,简单来说TypeScript 2.0 增加了对不可为空类型的支持(strictNullChecks),类似开启严格模式,但在我未配置strictNullChecks情况下,null依然无法赋值给void类型变量,希望有个大佬教教我
let v: void = undefined
// void代表没有类型,一般用于方法中没有返回值,所以void定义的函数不允许有返回值
function fn(): void {
// 禁止return
}
6)any类型
// any用来表示允许赋值为任意类型。
// 一个普通类型在赋值时改变类型是不允许的,但是any类型允许
let a: any = 'test'
a = 123
a = true
a = null
a = undefined
// any类型的变量的所有属性和方法都是可以被访问或调用的
let anyThing: any = 'test'
anyThing.name = 'anyName'
anyThing.setHeight(999)
// 如果无法确定某变量的类型时可以使用any类型
// 但是不推荐全篇使用any,如果都使用any类型将失去TS类型校验的作用,跟写JS一样,很不安全
小提一嘴: 类型推论
情况1: 变量在声明时未指定类型且未赋值的情况下,默认被认为时any类型
情况2: 变量在声明时未指定类型却赋值的情况下,ts会通过类型推论推测出一个类型,例如如果赋值是一个字符串,ts会推测为string类型
let value1 // 等价于 let value1: any
let value2 = 123 // 等价于 let value2: number = 123,那么该变量就不能接受除number类型外的赋值
7)unknown类型
TypeScript3.0中引入了unknown类型,与 any 一样,所有类型都可以分配给unknown.相比与比any,unknown类型更加严格当你要使用any 的时候可以尝试使用unknown
let un: unknown = 'test'
un = 123
un = true
un = null
un = undefined
un = []
// 1. 赋值问题
// 与any类型不同的是unknown类型不能作为子类型,而any可以作为父类型和子类型
// unknown类型不能赋值给其他值
let example1: unknown = 'test'
let number1: number = example1 // 报错
// any类型可以赋值给其他值
let example2: any = 'test'
let number2: number = example2
// unknown类型可赋值的对象只有unknown和any
let example3: any = 123
example3 = example1
// 2. 属性或方法问题
// 和any不同的是,unknown类型不可以调用不存在的方法或属性
example1.length
// 如果要调用,需要使用--断言(之后会更新)
(example1 as string).length
8)never类型
never 类型表示的是那些永不存在的值的类型,never 类型是任何类型的子类型,也可以赋值给任何类型:
但是,没有类型是 never 的子类型或可以赋值给 never 类型(除了 never 本身之外)。 即使 any 也不可以赋值给 never 。
let foo: neverfoo = 123 // 报错
和void的区别
没有显式返回值的函数会隐式返回 undefined 。尽管我们通常说这样的函数 “什么也不返回”,但实际上它是会返回的。在这些情况下,我们通常忽略返回值。在 TypeScript 中这些函数的返回类型被推断为 void 。
具有 never 返回类型的函数 永不返回 。它也不返回 undefined 。该函数没有正常完成,这意味着它可能会抛出异常或根本无法退出执行。
let bar: never = (() => { throw new Error('TypeScript never') })();
never类型运算
因为never是底部类型,所以任意类型与never交叉都得到never
type t1 = number & never //never
type t2 = boolean & never //never
以上结果可以理解为,如果将某类型的变量与never类型变量交叉,两个变量的结果只能赋值给never类型
同理,任意类型与never联合,都不会影响原有类型
type t3 = number | never //number
type t4 = boolean | never //boolean
以上结果可以理解为,如果某类型变量与never类型变量联合,结果都不会对某类型变量产生影响
再小提一嘴: 联合类型就是表示取值可以为多种类型中的一种,通过符号 ‘|’ 来分割,类似于逻辑判断‘或’的含义,变量值可以是联合类型中任意一个类型,举个栗子:
let example: string | number | undefined = '123'
let example: string | number | undefined = 123
let example: string | number | undefined = undefined
9)数组类型
在TypeScript中,数组类型有很多定义方式,很是灵活
类型+方括号
let arr1: number[] = [1, 2, 3, 4, 5]
//数组中不允许出现其他类型 包括使用数组方法时传入其他类型的参数
arr1 = [1, '2', 3, 4, 5] // 报错
let arr2: number[] = [1, 2]
arr2.push('3') // 报错
数组泛型,关于泛型以后再说
let arr3: Array = ['1', '2', '3', '4']
接口表示数组
interface Arr {
[index: number]: number
}
let arr4: Arr = [1, 2, 3, 4]
// 接口Arr代表,只要索引类型为数字时,那么这个值的类型必须是数字
类数组
比如arguments
function fun1() {
// 这样是错误的,因为arguments是一个类数组,不能用普通的数组方式描述,而应该用接口
let args: number[] = arguments
}
function fun2() {
// IArguments是ts内置的类型,常用的类数组都有自己的接口定义,如IArguments, NodeList, HTMLCollectionlet
args: IArguments = arguments
}
IArguments类型实际上就是以下代码
interface IArguments {
[index: number]: any;
length: number;
callee: Function;
}
any再数组中的应用,用any表示数组允许出现任意类型
let anyArr: any[] = [1, '1', true, { name: 'test' }]
学累了,告辞