我的总结
graph TD
Start --> Stop
1.TypeScript 是什么
TypeScript 是微软开发的开源编程语言。2012年10月,微软发布了首个公开版本的TypeScript,2013年6月19日,在经历了一个预览版之后微软正式发布了正式版TypeScript,可以在任何运行 JavaScript 的地方运行。TypeScript 起源于使用JavaScript开发的大型项目 。由于JavaScript语言本身的局限性,难以胜任和维护大型项目开发。因此微软开发了TypeScript ,使得其能够胜任开发大型项目。
- 简称:TS,是 JavaScript 的超集
- Ts官方文档
2.TypeScript和JS的对比
一下总结共四点
-
动态和静态编程语言
js属于动态类型的编程语言,TS属于静态类型的编程语言
js:边解释边执行,错误只能在运行阶段才能发现。 ts: 它要先编译,再执行(不能直接执行,需要编译成js才能执行)
-
ts完全兼容javascript,它可以编译成javascript
-
ts有类型支持,有强大的代码类型提示
在写代码的过程中就能发现问题
-
前端生态
前端三大框架: Vue 3 源码使用 TS 重写、Angular 默认支持 TS、React 与 TS 完美配合,TypeScript 已成为大中型前端 项目的首选编程语言。
目前,前端最新的开发技术栈:
- React: TS + Hooks
- Vue: TS + Vue3
3.TypeScript初体验
首先下包 npm i -g typescript
验证是否安装成功并查看版本号 tsc –v
注意:Mac 电脑安装全局包时,需要添加 `sudo` 获取权限:`sudo npm i -g typescript`
创建ts文件。例如 hello.ts 文件(注意:TS 文件的后缀名为.ts)
编译。将 TS 编译为 JS 输入 tsc hello.ts 此时,在同级目录中会出现一个同名的 JS 文件
在node中运行。在终端中输入命令 node hello.js
4.ts-node 简化运行 TS 的步骤
简化方式
使用 ts-node 包,直接在 Node.js 中执行 TS 代码。它提供了 ts-node 命令,可以简化执行命令。
装包 npm i -g ts-node
使用方式: ts-node hello.ts
ts-node 命令在内部偷偷的将 TS -> JS,然后,再运行 JS 代码
5.运行ts代码报错问题
如遇到以下错误
Cannot find name 'console'. Do you need to change your target library? Try changing the lib compiler option to include 'dom'
用
tsc --init命名,在根目录下生成配置文件 tsconfig.json
变量冲突
1.写代码时,用{ }整体给包起来
2.export{ }包裹
6.TS类型注解
什么是类型注解?
可以显示标记出代码中的意外行为,从而降低了发生错误的可能性
变量名: 类型 = 初始值
栗子
let name:string = 'jack'
let age:number = 18 (:number 就是类型注解)
注意 : 如果 let age: number = '18' 会直接报错
7.TS的类型
JS 已有类型
原始类型:`number/string/boolean/null/undefined/symbol`
对象类型:`object`(包括,数组、对象、函数等对象
TS 新增类型
联合类型
自定义类型(类型别名)
接口
元组
字面量类型
枚举
void
any
unkown
8.原始类型
number/string/boolean/null/undefined/symbol
// 数值类型
let age: number = 18
// 字符串类型
let myName: string = '小花'
// 布尔类型
let isLoading: boolean = false
// undefined
let un: undefined = undefined
// null
let timer:null = null
// symbol
let uniKey:symbol = Symbol()
9.类型推论
什么是类型推论?
在 TS 中,某些没有明确指定类型的情况下,TS 的类型推论机制会自动提供类型。好处:由于类型推论的存在,有些情况下的类型注解可以省略不写。
// 变量 age 的类型被自动推断为:number
let age = 18
// 函数返回值的类型被自动推断为:number
function add(num1: number, num2: number) {
return num1 + num2
}
一个实用的小技巧将鼠标放在所属方法或者对象上通过VsCode提示可以知道要传入的类型有哪些哦 : 例如下面这个图,提示你传的是dom节点
10.联合类型
什么是联合类型?
在Ts中以 | 链接,即有两个或者两个以上的其他类型组合成的类型叫做联合类型,可以表示可以是这些类型的任意一种类型
| 在vue中的过滤器也有这个用法
点击 查看过滤器如何使用
如 let 变量: 类型1 | 类型2 | 类型3 .... = 初始值
let arr: (number | string)[] = [1, 'a', 3, 'b']
let var1: string | number = 1
var1 = '1'
//定义一个定时器
let timeID:number|null =null
timeID=setTimeout(()=>{},1000)
冷知识 注意定时器返回的是number类型数据
11.类型别名
什么是类别别名?
顾名思义就是给类别叫一个别的名字
用法:
type 自己定义的名字 = 类型
type s = string // 定义
const str1:s = 'abc'
const str2:string = 'abc'
type 自己定义的名字= 类型 | 类型
type NewType = string | number
let a: NewType = 1
let b: NewType = '1'
12.数组类型
数组类型两种用法
let 变量: 类型[] = [值1,...]
let 变量: Array<类型> = [值1,...]
推荐写法一 简单
// 写法一:
let numbers: number[] = [1, 3, 5] // numbers必须是数组,每个元素都必须是数字
// 写法二:
let strings: Array<string> = ['a', 'b', 'c'] // strings必须是数组,每个元素都必须是字符串
13.函数-单个定义
普通函数 function 函数名( 类型=默认值,类型=默认值,...): 返回值类型 { }
箭头函数 const 函数名(类型=默认值,类型=默认值, ...):返回值类型 => { }
// 声明式
function add(num1: number, num2: number): number {
return num1 + num2
}
// 箭头函数
const add = (num1: number, num2: number): number => {
return num1 + num2
}
add(1,'1') // 报错
14.函数-统一定义函数格式
如 13上述 重复的代码可以使用更简洁的方法
将多个相同的代码定义为自定义类型
type Fn = (n1:number,n2:number) => number //定义一个自定义类型
const add1 : Fn = (a,b)=>{return a+b }
const add2 : Fn = (a,b)=>{return a-b }
15.函数-返回值类型void
在Ts中,如果函数没有返回值,使用void类型管理
有三种情况可以使用
- 不写return
- 写return ,但是后面不接内容
- 写return undefined
// 如果什么都不写,此时,add 函数的返回值类型为: void
const add = () => {
console.log('Hello')
}
// 如果return之后什么都不写,此时,add 函数的返回值类型为: void
const add = () => {
return
}
const add = (): void => {
// 此处,返回的 undefined 是 JS 中的一个值
return undefined
}
// 这种写法是明确指定函数返回值类型为 void,与上面不指定返回值类型相同
const add = (): void => {}
16.函数-可选参数
可选参数可传可不传
用法:function fn(count1?:number,count2?number):void{}
fn(1)
注意可选参数不能与默认参数一起使用
function mySlice(start?: number=0, end?: number=11): void {} 报错!!!
17.对象类型-单独使用
可配合可选参数使用===>
const 对象名: {
属性名1:类型1,
属性名2:类型2,
方法名1(形参1: 类型1,形参2: 类型2): 返回值类型,
方法名2:(形参1: 类型1,形参2: 类型2) => 返回值类型
} = { 属性名1: 值1,属性名2:值2 }
const fn:{
name: string,
price: number,
func: ()=>string,
age?:number
} = {
name: '手机',
price: 2000,
func:function(){ return '打电话' }
}
18.对象类型-类型别名
type obj={
name:string,
age:number
sayHi():void
}
let Fn:obj={
name:'jack',
age:18,
sayHi(){
console.log('Hello')
}
}
19.接口
用法: interface 接口名 {属性1: 类型, 属性2: 类型,}
interface(接口)和 type(类型别名)的对比:
-
相同点:都可以给对象指定类型
-
不同点:
- 接口,只能为对象指定类型。它可以继承。
- 类型别名,不仅可以为对象指定类型,实际上可以为任意类型指定别名
interface IGoodItem {
name: string,
price: number,
func: ()=>string
}
const good1: IGoodItem = {
name: '手表',
price: 200,
func: function() {
return '看时间'
}
}
const good2: IGoodItem = {
name: '手机',
price: 2000,
func: function() {
return '打电话'
}
}
20.接口继承
如果遇到一下情景,可以使用继承,将公共的属性抽离出来,再定义
interface IPoint2D { x: number; y: number }
interface IPoint3D { x: number; y: number; z: number }
写法
interface 接口2 extends 接口1 {
属性1: 类型1, // 接口2中特有的类型
...
}
运用
interface Point2D { x: number; y: number }
// 继承 Point2D
interface Point3D extends Point2D {
z: number
}
这样Point3D就继承了Point2D的两个属性,再定义一个z属性
21.元组
什么是元组?
固定数组只能有几个值,且定义类型
即元组是一种特殊的数组。有两点特殊之处:
- 它约定了的元素个数
- 它约定了特定索引对应的数据类型
用法
//例如经纬度只能有两个数字
let position: [number, number] = [39.5427, 116.2317]
//模拟定义useState
function useState(num:number):[number,(number)=>{void}]{
setUpdataNum(newnum)=>{
num=newnum
}
return [num, setUpdataNum]
}
const [num,setnum]=useState(10)
22.字面量类型
任意字面量都可以作为类型使用,如let a: 'abc' = 'abc'
type Gender = 'girl' | 'boy'
let g1: Gender = 'girl' // 正确
let g2: Gender = 'boy' // 正确
let g3: Gender = 'man' // 错误
优势:相比于 string 类型,使用字面量类型更加精确、严谨