TS学习笔记

typescript 是具有类型语法的 javascript,是一门强类型的编程语言

  •  ts = js + type(类型)
  • js 是弱类型语言,变量可以赋不同类型的值
  • ts 是强类型语言,变量不能做随意类型赋值

TS的优点

  1. 静态类型检查,提前发现代码错误
  2. 良好的代码提示,提高开发效率

使用建议

  1. 更适合开发中大型项目
  2. 通用的JS代码库
  3. 团队协作开发

搭建编译环境

为什么需要编译环境:TS代码无法在JS引擎中运行(如浏览器、NodeJs),需要编译成JS代码才可以正常运行

1. 搭建手动编译环境(仅用于测试,可直接进行下一步)

  1. 全局安装 typescript 包  ->  注册 tsc 命令:npm install -g typescript

                检查引擎版本:tsc -v

  1. 新增 hello.ts 文件,执行 tsc hello.ts 命令生成 hello.js文件
  2. 执行 node hello.js 运行js文件查看效果

2. 搭建工程化下的自动编译环境

2.1在终端内运行命令,创建项目

npm create vite@latest ts-pro -- --template vanilla-ts
  • npm create vite@latest:创建最新版本的vite项目
  • ts-pro:项目名称
  • -- --template vanilla-ts创建项目使用的模版为原生TS模版

2.2 运行项目

  • cd ts-pro
  • npm install
  • npm run dev    -> 打开项目
  • 在main.ts 文件内写TS代码,在浏览器内查看控制台输出的信息

实际工作中不需要我们手动编译代码,由工程化内置,自动编译

TS类型注解

概念:给变量添加类型约束,使变量只能被赋值为约定好的类型,同时可以有相关的类型提示

注:注解为全小写(如:string) 

1. TS支持的常用类型注解

  • JS已有类型
    1. 简单类型:number string boolean null undefined
    2. 复杂数据类型:数组 函数
  • TS新增类型:联合类型、类型别名、接口(interface)、字面量类型、泛型、枚举、void、any 等

2. 语法

2.1 注解数组

 语法一(推荐):

  • 类型[ ] 
  • 如:arr1: number[] = [1, 2, 3]

语法二:

  • 泛型写法
  • 如:arr2: Array<number> = [1, 2, 3]

2.2 联合类型(较复杂,通常用 类型别名 来简化)

  • 作用:将多个类型连合成一个类型对变量进行注解 
  • 如:arr: (number | string)[] = [1, 2, 3, '1', '2', '3']

2.3 类型别名

  • 通过type关键词给写起来较复杂的类型起一个其它的名字
  • 好处:用来 简化 和 复用 类型
type ItemType = (string | number)[]
const arr: ItemType = ['aaa', 100]

2.4 函数类型

概念:给函数添加类型注解,本质上是给函数的 参数和返回值 添加类型约束

  • 参数注解类型后不但限制了参数的类型还限制参数为必传
  • 返回值注解后限制了函数内部return出去的值必须满足类型要求

好处:

  • 避免因为参数不对导致的内部逻辑错误
  • 对函数起到说明的作用

 类型:

        1. 函数声明
function add(a: number, b: number): number {
    return a + b
}

add(1, 2)

let res: number
res = add(3, 4)
    2. 函数表达式  

                1. 参数和返回值分开注解

const add1 = (a: number, b: number): number => {
  return a + b
}
add1(3, 4)

                2. 函数整体注解(只针对于函数表达式)-  通常在库文件里使用

type AddFn = (a: number, b: number) => number
const add2: AddFn = (a, b) => {
  return a + b
}
add2(1, 2)

可选参数:(必须在所有参数的末尾)

        概念:当前参数可传可不传,一旦传递参数必须保证参数类型正确

function buileName(firstName: string, lastName?: string): string {
  if (lastName) {
    return `${firstName}${lastName}`
  } else {
    return firstName
  }
}
console.log(buileName('foo'));
console.log(buileName('foo', 'bar'));

无返回值:

概念:有些函数只有功能没有返回值是可以用void进行返回值注解,明确表示函数没有函数值

注:在JS中如果没有返回值,默认返回undefined,在TS中void和undefined不是一回事,undefined在TS中是一种明确的简单类型,如果指定返回值为undefined,那返回值必须是undefined类型

function eachArr(arr:number[]):void{
  arr.forEach((item)=>{
    console.log(item);
  })
}

2.5 interface接口类型

作用:在TS中使用interface接口来描述对象数据的类型(常用于给对象的属性和方法添加类型约束)。限制的是接口的属性和对象的类型

注:一旦注解接口类型后对象的属性和方法类型都需要满足要求,属性不能多也不能少

典型场景:比较典型的是前后端数据通信的场景

  1. 前端向后端发送数据:收集表单对象数据是的类型校验
  2. 前端使用后端数据:渲染后端对象数组列表是的智能提示
interface Person {
  name: string
  age: number
}
const amtb: Person = {
  name: 'amtb',
  age: 18
}

可选设置:

        概念:通过 对属性进行可选标注,赋值的时候该属性可以缺失,如果有值必须保证类型满足要求

interface Props {
  type: string
  size?: string
}
let props: Props = {
  type: 'success',
}
props = {
  type: 'success',
  size: 'large'
}

继承:

        概念:接口的属性是可以进行类型复用的。使用 extends 实现接口继承,实现类型复用。解决接口复用问题

interface GoodsType {
  id: string,
  price: number
}
interface DisGoodsType extends GoodsType {
  disPrice: number
}
let goods: DisGoodsType = {
  id: '1001',
  price: 200,
  disPrice: 180
}

嵌套结构:先里后外的方式进行定义

interface Data {
  title: string
  content: string
}
interface resData {
  code: number
  msg: string
  data: Data
}
let resData = {
  code: 200,
  msg: 'success',
  data: {
    title: 'aaa',
    content: 'bbb'
  }

2.6 type注解对象类型

        概念:对象数据类型注解除interface外还可以使用类型别名进行注解,作用类似

        区别:type定义时需要加 =

type Person = {
  name: string
  age?: number
}
let p: Person = {
  name: 'amtb',
}
p = {
  name: 'amtb',
  age: 18
}

        继承:type + 交叉类型模拟继承   -   类型别名配合交叉类型(&)

type GoodsType = {
  id: string
  price: number
}
type DisGoodsType = GoodsType & {
  disPrice: number
}
let goods: DisGoodsType = {
  id: '1001',
  price: 200,
  disPrice: 180
}

interface 和 type 对比:推荐使用type(更灵活)

相同:

  • 都能描述对象类型
  • 都能实现继承
    • interface使用extends
    • type配合交叉类型 &

不同:

  • type除了能描述对象,还可以用来自定义其它类型
  • 同名的interface会合并(属性取并集,不能出现类型冲突),同名type会报错
// 同名的interface - 合并
interface Item {
  name: string
}
interface Item {
  age: number
}
let item: Item = {
  name: 'amtb',
  age: 18
}

// 同名的type - 报错
type Item1={}
type Item1={}

2.7 字面量类型

概念:使用js字面量作为类型对变量进行类型注解,这种类型就是字面量类型

优势:类型更加精确,提供精确的可选值范围

实际应用:通常和联合类型结合起来使用,提供一个精确的可选范围

2.8 类型推论

概念:在TS中存在类型推断机制,在没有给变量添加类型注解的情况下,TS也会给变量提供类型

建议:

  1. 开发项目时,能省略类型注解的地方就省略
  2. 刚开始学TS,建议所有类型都加上,先熟悉
  3. 鼠标放至变量上,VsCode会自动提示类型

​​​​​​2.9 any类型

作用:变量被注解为any类型之后,TS会忽略类型检查,错误的类型赋值不会报错,也不会有任何提示

注:尽量避免使用any。any使用的越多,程序可能出现的漏洞越多

2.10 泛型接口:<T>

概念:在定义接口、函数等类型的时候,不预先指定具体的类型,而是在使用时再指定类型

优点:增加类型的复用性灵活性

语法:在接口类型名称后面使用<T>即可声明一个泛型参数,接口里的其他成员都能使用该参数的类型

实现的基本方法:

  1. 定义参数:找到可变的类型部分通过泛型<T>抽象为泛型函数
  2. 传惨在使用泛型时,把具体类型传入到泛型参数位置
interface User {
  name: string
  age: number
}
interface Goods {
  id: string,
  price: number
}
interface ResData<T> {
  code: number
  msg: string
  data: T
}

let user: ResData<User> = {
  code: 200,
  msg: 'success',
  data: {
    name: 'amtb',
    age: 18
  }
}
let goods: ResData<Goods> = {
  code: 200,
  msg: 'success',
  data: {
    id: '1001',
    price: 100
  }
}

2.11 泛型别名

语法:在类型别名type后面使用<T>即可声明一个泛型函数,接口里的其他成员都能使用该参数的类型

type User = {
  name: string
  age: number
}
type Goods = {
  id: string,
  price: number
}
type ResData<T> = {
  code: number
  msg: string
  data: T
}

let user: ResData<User> = {
  code: 200,
  msg: 'success',
  data: {
    name: 'amtb',
    age: 18
  }
}
let goods: ResData<Goods> = {
  code: 200,
  msg: 'success',
  data: {
    id: '1001',
    price: 100
  }
}

2.12 泛型函数

语法:在函数名称后面使用<T>即可声明一个泛型函数,整个函数中(参数、返回值、函数体)的变量都可以使用该参数的类型

function fn<T>(){}
function createArray<T>(length: number, value: T) {
  let result = []
  for (let index = 0; index < length; index++) {
    result[index] = value
  }
  return result
}
createArray<string>(4, '10')
createArray<number>(4, 10)

2.13 泛型约束

作用:泛型的特点就是灵活不确定,有些时候泛型函数的内部需要访问一些特定类型的数据才有的属性,此时会有类型错误,需要通过泛型约束解决

        既可以保留泛型的灵活性,又做了特定的限制

// 报错
function logLen<T>(obj: T) {
  console.log(obj.length);
}

// 泛型约束
interface lengthObj {
  length: number
}
function logLen1<T extends lengthObj>(obj: T) {
  console.log(obj.length);
}
logLen1({ length: 10 })
logLen1(['100'])

类型断言

作用:有时候开发者比TS本身更清粗当前的类型是什么,可以使用断言(as)让类型更加精确和具体

注:类型断言只能「欺骗」TS编译器,无法避免运行时的错误,滥用类型断言可能会导致运行是错误

const link = document.getElementById('link') as HTMLAnchorElement
console.log(link.href);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值