TS 入门指南

TS 类型基本用法

TS简介

  • TypeScript,简称 TS, 是一种由微软开发的编程语言,它是对 JavaScript 的一个增强
  • 让我们更加方便地进行类型检查和代码重构,提高代码的可靠性和可维护性
  • 同时,TypeScript 还支持 ECMAScript 的最新特性

搭建学习环境 

进入 Node 官网安装

安装完成后使用以下命令查看是否安装完成: 安装完成后使用以下命令查看是否安装完成: 

  • node -v
  • npm -v

继续安装 nrm 管理包源:

  • npm i nrm -g
  • nrm ls
  • nrm use taobao

全局安装 typescript:

  • npm i typescript -g

全局安装 ts 的编译工具,使用 ts-node 可以将 ts 文件执行

  • npm i ts-node -g
    • 使用:ts-node index.ts
  • 安装 ts-node 依赖包:npm install tslib @types/node -g

使用 TS 可以有良好的提示,使代码可读性变强,更提前发现问题

TS 类型

  • TS 出现弥补的 JS 的类型缺失
  • 众所周知,代码错误越早发现越好,代码编写 > 代码编译 > 代码运行 开发 > 测试 > 上线
  • Vue2 使用 Flow 进行类型检查,后续 Vue3 也使用 Typescript 重写
  • TS 代码要运行在浏览器,需要进行类型擦除,转换为 JS 代码
  • TS 类型包含所有 JS 类型 null、undefined、string、number、boolean、bigInt、Symbol、object(数组,对象,函数,日期)
  • 还包含 void、never、enum、unknown、any 以及 自定义的 type 和 interface

变量声明

  • var/let/const 标识符: 数据类型 = 赋值

手动指定数据的类型(类型注解),不要写成大写的 String ,因为这是 JS 的一个内置类

const data: string = 'hello'

型定义的时候已经决定

类型推导

  • 如果没有明确指定类型,TS 会隐式的推导出一个类型
  • 这类型根据赋值的类型推断,没有赋值则为 any 类型,能自动推导出类型,没必要手动指定

 基础类型

 

数组和元组 

Array<元素类型>这种写法可能会存在与jsx冲突问题
const arr1: Array<number> = [1, 2, 3]
元素类型后面接上[],表示由此类型元素组成的一个数组
[const arr2: number[] = [1, 2, 3]
数组里面可能有字符串和数组
const arr3: (string | number)[] =
[1,2,'黛玉']
//元组已知元素数量和类型的数组,元组一定要指明类型
const tuple:[string, number] = ['云牧', 18]

  • tuple可以作为函数返回的值,React 的 useState 就是个元组,类似于
function useState<T>(state: T): [T, (newState: T)=> void]
let currentState = state
const changeState = newState
currentState = newState
}
return [currentState, changeState]
[const [count, setCount]= useState(10)

对象类型

  • TS 中的 object 类型泛指所有的的非原始类型,如对象、数组、函数
  • 下面我们使用 object 声明了这个对象,但是这个对象既不能设置新数据,也不能修改老数据
const obj: object = {
name:'云牧',
}
obj.age = 18
obj.name='黛玉'

  • 下面这种对象类型的限制才更为精确
  • 可限制对象每个属性的类型
const p1:{name: string; age:number } = { name:'黛玉',age:18}
// 问号,代表某个属性可选,不一定需要
const p2: { name: string; age?: number } = {I name:'云牧'}

any、unknown、never

  • 无法确定一个变量的类型,可使用 any,此时在其身上做任何操作都是合法的,即使访问了一个不存在的属性
  • 如果某些情况处理类型过于繁琐,或者在引入一些第三方库时,缺失了类型注解,这个时候 我们可以使用 any,更多是为了兼容老代码
function anyType(msg: any) {
console.log(msg)
}

  • unknown 类型表示一个值可以是任何类型,它是所有类型的父类型,任何类型都可以赋值给 unknown 类型,但是 unknown 类型只能赋值给 any 类型和 unknown 类型本身
  • 类似 any,与 any 类型不同的是,unknown 类型的变量不能直接赋值给其他类型的变量,也不能调用其上的任何方法或属性,除非先进行类型检查或类型断言,这样确保运行时的类型安全
  • 默认在其操作都是不合法的,主要是在编写通用代码时,例如编写库或框架时,需要处理来自不同来源的数据,但又不确定数据的类型
//类型判断后才能使用 unknown类型数据
function foo(arg: unknown) {
  if (typeof arg == 'string') {
     console.log(arg.toUpperCase())
   } else if (typeof arg == 'number') {
     console.log(arg.toFixed(2))
  }
}
//类型断言后使用
function bar(arg: unknown) {
  const num = arg as number
  console.log(num.toFixed(2))
}

  • 假如一个函数的返回结果是死循环或者异常,我们可以使用 never 类型表示这种永不存在值的类型
  • 它是一个底层类型,不是任何类型的子类型,也没有任何子类型
  • 更多情况是封装工具库时候可以使用,比如下面这段代码,如果单纯在函数参数的类型多加一个参数,而没有对应 case 处理,则会报错
function handleMsg(msg: string | number) {
switch (typeof msg) {
case 'string
break
}
case 'number':
break
default: {
const check: never = msg
}
handleMsg('hello')
handleMsg(10)

 never 会在联合类型被直接移除

函数类型

  • 声明函数时,可以在每个参数后添加类型注解,声明其参数类型
  • 同样也可以声明返回值的类型,不过也可以不写让 TS 自动推导
  • 函数参数的一般顺序 必传参数 - 有默认值的参数 - 可选参数

 

枚举类型

  • 枚举类型将一组可能出现的值,一个个列举,定义在一个类型中,这个类型就是枚举

 

这种字符串的枚举可能使用 type Direction = 'LEFT' | 'RIGHT' | 'TOP' | 'RIGHT'可能会更好点 

type Direction = 'LEFT'|'RIGHT'|'TOP'|'BOTTOM'
function turnDirection(direction: Direction) {} 
turnDirection('LEFT')

interface 和 type

基本使用

  • 使用 interface 定义接口,使用 type 定义类型别名
  • 都可以约束对象的结构
// 方式一:使用interface
interface IPoint{
 x: number
 readonly y: number // readonly代表只读
 z?:number //?代表可选
}
// 方式二:使用type
type Point = {
  X: number
  y: number
}

区别

  1. interface 只描述对象,type 则可以描述所有数据
  2. interface 使用 extends 来实现继承,type 使用 & 来实现交叉类型
  3. interface 会创建新的类型名,type 只是创建类型别名,并没有创建新类型
  4. interface 可以重复声明扩展,type 则不行(别名是不能重复的)

 索引签名(Index Signatures)

接口继承

  • 接口和类继承相同,都是使用 extends 关键字
  • 接口是支持多继承的(类不支持多继承)

interface Animal {
 running: () => void
}
interface Person{
 name: string
 age: number
}
//自动扩展 Person类型
interface Person {
 sex: string
}

// 手动使用 extends 继承
interface Student extends Person, Animal {
  id: number
}
const u: Student = { name:'云牧',age:18, sex: 'male', id: 1, running() }

接口实现

  • 定义的接口可以被类实现
  • 之后如果需要传入接口的地方,同样也可以将类实例传入
  • 这就是面向接口开发

interface IRun {
 running: () => void
}
interface IEating {
 eating:() => void
}
class Person implements IRun, IEating {
running(){}
eating(){}
}
function run(runner: IRun) {
  runner.running()
}
constp = new Person()
run(p)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

好喝的西北风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值