TypeScript笔记(ts简介、环境搭建、基础)

160 阅读7分钟

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代码,没有报错便编译成功

2022-09-20-15-18-59-image.png

报错:如果报错tsc:无法加载文件,可以以管理员身份打开Powershell,执行set-ExecutionPolicy RemoteSigned命令

set-ExecutionPolicy RemoteSigned

将执行策略更改为RemoteSigned,在询问更改执行策略时选择Y或A,更改完成后重新打开vscode或终端再次执行编译命令既可:

2022-09-20-15-23-33-image.png 运行后会自动在.ts文件同一目录下会生成相应文件名的.js文件

2022-09-20-15-14-27-image.png

使用node命令执行该js文件,即可运行代码

2022-09-20-15-15-57-image.png

每次手动编译很麻烦,也可以使用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' }]

学累了,告辞