第一章 TypeScript简介
0、TypeScript简介
- TypeScript是JavaScript的超集。
- 它对JS进行了扩展,向JS中引入了类型的概念,并添加了许多新的特性。
- TS代码需要通过编译器编译为JS,然后再交由JS解析器执行。
- TS完全兼容JS,换言之,任何的JS代码都可以直接当成JS使用。
- 相较于JS而言,TS拥有了静态类型,更加严格的语法,更强大的功能;TS可以在代码执行前就完成代码的检查,减小了运行时异常的出现的几率;TS代码可以编译为任意版本的JS代码,可有效解决不同JS运行环境的兼容问题;同样的功能,TS的代码量要大于JS,但由于TS的代码结构更加清晰,变量类型更加明确,在后期代码的维护中TS却远远胜于JS。
1、TypeScript 开发环境搭建
- 下载Node.js -> 安装Node.js
- 使用npm全局安装typescript
- 进入命令行
- 输入:npm i -g typescript
- 创建一个ts文件
使用tsc对ts文件进行编译
- 进入命令行
- 进入ts文件所在目录
- 执行命令:tsc xxx.ts
- 如果需要 自动编译文件,使用 -w 指令后,TS编译器会自动监视文件的变化,并在文件发生变化时对文件进行重新编译。
tsc xxx.ts -w
生成js文件后,变量会跟ts冲突(默认都是全局变量),只需要在ts文件头部加入
export default {}让其被认定为模块即可2、常用类型
- 类型声明
- 类型声明是TS非常重要的一个特点
- 通过类型声明可以指定TS中变量(参数、形参)的类型
- 指定类型后,当为变量赋值时,TS编译器会自动检查值是否符合类型声明,符合则赋值,否则报错
- 简而言之,类型声明给变量设置了类型,使得变量只能存储某种类型的值
- 语法:
- ```typescript let 变量: 类型;
let 变量: 类型 = 值;
function fn(参数: 类型, 参数: 类型): 类型{ … }
- 自动类型判断
- TS拥有自动的类型判断机制
- 当对变量的声明和赋值是同时进行的,TS编译器会自动判断变量的类型
- 所以如果你的变量的声明和赋值时同时进行的,可以省略掉类型声明
- 类型:
| 类型 | 例子 | 描述 |
| --- | --- | --- |
| number | 1, -33, 2.5 | 任意数字 |
| string | 'hi', "hi", `hi` | 任意字符串 |
| boolean | true、false | 布尔值true或false |
| 字面量 | 其本身 | 限制变量的值就是该字面量的值 |
| any | * | 任意类型 |
| unknown | * | 类型安全的any |
| void | 空值(undefined) | 没有值(或undefined) |
| never | 没有值 | 不能是任何值 |
| object | {name:'孙悟空'} | 任意的JS对象 |
| array | [1,2,3] | 任意JS数组 |
| tuple | [4,5] | 元素,TS新增类型,固定长度数组 |
| enum | enum{A, B} | 枚举,TS中新增类型 |
- number
```typescript
let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
let big: bigint = 100n;
boolean
let isDone: boolean = false;string ```typescript let color: string = “blue”; color = ‘red’;
let fullName: string = Bob Bobbington;
let age: number = 37;
let sentence: string = `Hello, my name is ${fullName}.
I’ll be ${age + 1} years old next month.`;
- 字面量
- 也可以使用字面量去指定变量的类型,通过字面量可以确定变量的取值范围
```typescript
let color: 'red' | 'blue' | 'black';
let num: 1 | 2 | 3 | 4 | 5;
- any(可以赋予给任何类型的变量 不安全)
let d: any = 4; d = 'hello'; d = true;unknown (any升级版,不能随意赋值其他变量)
unknown 是 TypeScript 3.0 中添加的一个类型,它主要用来描述类型并不确定的变量。和any的区别就是会进行类型检测。 ```typescript let unk: unknown; let x = 1; let y = “2”; if (x) { unk = x; } else { unk = y; }
// 使用unknown后,typescript会做类型检测 unk.toFixed(2); // 报错 // any会绕过类型检测,所以下面不会有问题提示 let an1: any; an1.toFixed(2);
// 通过缩小类型可以通过类型检测 if (typeof unk === ‘number’) { unk.toFixed(2); }
- void
```typescript
let unusable: void = null || undefined;
function fn (): void{
return null || undefined;
}
- never
function error(message: string): never { throw new Error(message); }object(万物皆对象 一般不写以下第一行)
```typescript let obj: object = {};
//对象一般这样写 let h : {name: string}; h={name:’iv’};
//?表示属性可选 let i:{name:string,age?:number} i={name:’iv’}; i={name:’iv’,age:29};
//[propName: string] any表示任意类型的属性 let j:{name:string,[propName: string]:any}; j={name:’iv’,age:29,size:1,gender:’女’};
//作为函数参数时 function printName(obj: { first: string, last?: string }) { //因为last可先参数 先判断 if (obj.last !== undefined) { console.log(obj.last.toLowerCase()) } //使用? ts判断 console.log(obj.last?.toUpperCase()) }
<a name="WIkcM"></a>
### array
```typescript
let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];
tuple (元组:有长度限制)
//长度为2的数组
let x: [string, number];
x = ["hello", 10];
//数组里边的子项为数组 长度为2
let arry:[string,number][]=[
["hello", 10],
["hello", 10]
]
null & undefined & !非空断言运算符
JavaScript 有两个原始值用于表示不存在或未初始化的值: null(不存在) 和 undefined (未初始化)
let x: undefined = undefined
let y: null = null
//使用判断来缩小检查可能的值
function doSomething(x: string | null) {
if (x === null) {
// 做一些事情
} else {
console.log('Hello, ' + x.toUpperCase())
}
}
//非空断言运算符( ! 后缀)即该值不是 null or undefined
function liveDangerously(x?: number | null) {
console.log(x!.toFixed())
}
enum (枚举)
枚举的作用在于定义被命名的常量集合,一个默认从 0 开始递增的数字集合,称之为数字枚举。也可以指定值,这里可以指定的值可以是数字或者字符串。
//默认red=0
enum Color {
Red,
Green,
Blue,
}
let c: Color = Color.Green;
//此时green为2
enum Color {
Red = 1,
Green,
Blue,
}
let c: Color = Color.Green;
//此时按照赋值
enum Color {
Red = 1,
Green = 2,
Blue = 4,
}
let c: Color = Color.Green;
//枚举一般用于此处
let p : {name:string,like:Color};
p={name:'iv',like:Color.pink}
console.log(p.like === Color.pink);//true
union( | )联合类型
可以是多种类型选择
function welcomePeople(x: string[] | string) {
if (Array.isArray(x)) {//数组时
console.log('Hello, ' + x.join(' and '))
} else {//字符串时
console.log(x.toUpperCase())
}
}
welcomePeople('A')
welcomePeople(['a', 'b'])
type类型别名
可以多次使用 同一个类型,并用一个名称来引用它
type Point = {
x: number
y: string
}
function printCoord(pt: Point):Point['x'] {
return 123
}
printCoord({
x: 100,
y: 'hello'
})
//扩展
type Animal = {
name: string
}
type Bear = Animal & {
honey: boolean
}
const bear: Bear = {
name: 'winnie',
honey: true
}
interface接口
类似类型别名
interface Point {
x: number
y: number
}
function printCoord(pt: Point):Point['x'] {
return 123
}
printCoord({
x: 100,
y: 200
})
//接口的继承(扩展)
interface Animal {
name: string
}
interface Bear extends Animal {
honey: boolean
}
const bear: Bear = {
name: 'winie',
honey: true
}
// 向现有的类型添加字段 (重复命名相当于叠加(type类型创建后是不能更改的,这点是与接口的区别))
interface MyWindow {
count: number
}
interface MyWindow {
title: string
}
const w: MyWindow = {
title: 'hello ts',
count: 100
}
3、类型断言
一般类型断言
有些情况下,变量的类型对于我们来说是很明确,但是TS编译器却并不清楚,此时,可以通过类型断言来告诉编译器变量的类型,断言有两种形式:
//as const转化为元组 let arry = [‘dan’, 18] as const //arry.push(1)
//结构中使用 as const来确定类型 function fn() { let str: string = ‘dan’ let fun = (a: number, b: number): number => a + b
// return [str, fun] 这样写呗调用时不知道类型 //三种方法确定返回值类型 //return [str, fun] as [string, Function] //return [str, fun] as [typeof str, typeof fun] return [str, fun] as const }
let [nstr, nfun] = fn();
nfun(1, 2)
<a name="uhIFF"></a>
### dom的非空断言 (!)
```typescript
//获取的元素可能是null (HTMLDivElement | null)
//如果直接el.xx会报错
//方法1 断言为div元素
// let el: HTMLDivElement | null = document.querySelector('.box') as HTMLDivElement
//方法2 直接断言为非空
let el = document.querySelector('.box')!
el.innerHTML = 'dan'
4、类型缩小
typeof类型守卫
JavaScript 支持一个 typeof 运算符 来缩小类型范围
“string” “number” “bigint” “boolean” “symbol” “undefined” “object” “function”
function printAll(strs: string | string[] | null) {
//使用typeof来判断
//但是这么写是错的 因为在 JavaScript 中, typeof null 实际上也是 "object"
//提示错误: strs可能是null ,
//解决1: 最外层套if (strs !== null) {} 解决2:下方"真值缩小"案例第二种解决方法
if (typeof strs === "object") {
for (const s of strs) {
console.log(s);
}
} else if (typeof strs === "string") {
console.log(strs);
} else {
// 做点事
}
}
真值缩小
if 条件语句,将它们的条件“强制”转化为 boolean。 除了以下值其他都为true。
- 0
- NaN
- “” (空字符串)
- 0n ( bigint 零的版本)
- null
- undefined
Boolean 函数中运行值获 得 boolean ,或使用较短的双布尔否定将值强制转换为 boolean 。(后者的优点是 TypeScript 推断出 一个狭窄的文字布尔类型 true ,而将第一个推断为 boolean 类型。)function printAll(strs: string | string[] | null) { //利用if判断强制转换strs 如果是null则为false if (strs && typeof strs === "object") { for (const s of strs) { console.log(s); } } else if (typeof strs === "string") { console.log(strs); } }// 这两个结果都返回 true Boolean("hello"); // type: boolean, value: true !!"world"; // type: true, value: true导入导出
导出各种
导入时可以用type来区分
