前端优化之ts优化经验总结

最近为负责的一个移动端项目(基于vue3+ts)做了ts的类型补充与优化

你问为什么要优化?

皆因一开始大家决定使用ts的时候都是一拍脑袋,觉得应该跟上潮流,结果写着写着就要么变成anyscript,要么就是直接强行忽略类型检查(啥也看不见),本强迫症看着一堆红色波浪线(错误提示)实在是难受,于是就开始了一顿整,边整边记录,虽然也是有一些投鸡取巧,不过也算是一次经验吧

我保证,以后一定好好写类型声明😭

首先,更投机取巧的方法:

为不想ts帮你检查的代码的上方增加一行以下代码

// @ts-ignore*

这样就不会有红色波浪线(忽略了类型检查)

但咱们是有素质的打工人,怎么可以这样!!还是正经搞吧!

首先得知道,哪些文件没有正确进行类型声明

通过运行命令,在控制台输出类型检查结果:

// 需要编译
npm install -g tsc

// 运行以下命令,即可输出未通过类型检查的文件和具体出处
tsc --noEmit
// 仅类型检查
npm install -g vue-tsc

// 运行以下命令,即可输出未通过类型检查的文件和具体出处
vue-tsc --noEmit

具体区别看下文:

  1. vue-tsc 命令和 tsc 命令都是用于执行 TypeScript 类型检查的工具,但它们的使用场景略有不同。
  2. tsc 命令:tsc 是 TypeScript 编译器的命令行工具,用于将 TypeScript 代码编译为 JavaScript。它可以执行类型检查,并且还可以将 TypeScript 代码转换为 JavaScript 代码。tsc 命令会根据项目中的 tsconfig.json 文件中的配置进行类型检查和编译
  3. vue-tsc 命令:vue-tsc 是专门为 Vue 单文件组件(.vue 文件)设计的 TypeScript 类型检查工具。它是对 tsc 命令的封装,可以在检查 Vue 文件时解析其中的 script 标签部分,并进行类型检查。vue-tsc 命令会根据项目中的 tsconfig.json 文件中的配置进行类型检查。

基于js模块文件提供ts类型检查支持,避免引用js模块时类型检查报错

添加.d.ts文件进行声明,.d.ts 文件用于为 JavaScript 代码提供类型声明。下面是一个示例,展示如何使用 .d.ts 文件来为 JavaScript 代码添加类型信息。

假设我们有一个 JavaScript 文件 themeColors.js,其中定义了一个对象 themeColors,它包含了多个属性来表示不同的主题颜色。

// themeColors.js

const themeColors = {
  theme: 'blue',
  themeLight: 'lightblue',
  themeDark: 'darkblue',
  // 其他属性...
};

export default themeColors;

为了为这个 JavaScript 文件添加类型信息,我们可以创建一个 .d.ts 文件,命名为 themeColors.d.ts,并在其中声明一个模块,定义 ThemeColors 接口来描述 themeColors 对象的类型

// themeColors.d.ts

declare module '@/core/themeColors.js' {
  interface ThemeColors {
    theme: string;
    themeLight: string;
    themeDark: string;
    // 其他属性...
  }

  const themeColors: ThemeColors;
  export default themeColors;
}

在这个 .d.ts 文件中,我们使用 declare module 来声明一个模块,模块名为 @/core/themeColors.js,并在模块内部定义了一个接口 ThemeColors,描述了 themeColors 对象的类型。然后,我们使用 const 关键字定义了一个常量 themeColors,并将其导出。

现在,我们可以在其他 JavaScript 或 TypeScript 文件中使用 themeColors 对象,并享受类型检查的好处。

// otherFile.js

import themeColors from '@/core/themeColors.js';

console.log(themeColors.theme); // 输出 'blue'
console.log(themeColors.themeLight); // 输出 'lightblue'
// 其他属性的访问...

通过这种方式,我们可以在 JavaScript 代码中使用 .d.ts 文件提供的类型信息,从而获得更好的代码提示和类型检查

对于interface中定义为动态属性的值,取值为其他指定类型的变量赋值时报类型错误:不能将类型“number | undefined”分配给类型“number”

interface Opt {
  page?: number
  data: string[]
}

// 取值
const res: Opt = {
	data: []
}
let num:number = 0
const { page, data } = res
num = page
// 不能将类型“undefined”分配给类型“number”。ts(2322)
// 因为动态类型有可能类型为undefined, 而num变量的类型是number

解决:取值时为动态属性赋默认值

// 为动态属性page设置默认值,则不会抛类型不匹配错误
const { page = 1, data } = res
num = page

类型推断的使用 — 万能的【as】

// 场景一、不想重复定义初始值,而又不想为interface的所有属性改为非必填选项(其实有点投机取巧)
export interface ExpressInfo {
  "context":string // 内容
  "time": string // 时间,原始格式
  "status": string //对应的物流状态名称或者高级状态名称
  "statusCode": string // 高级物流状态值
  "areaCode": string // 行政区域的编码
  "areaName": string // 行政区域的名称
  "areaCenter": string // 行政区域经纬度
  "location": string // 快件当前地点
  "areaPinYin": string // 行政区域拼音
}

// 定义一个变量,类型为ExpressInfo ,但由于我有点懒,不想维护两套字段,但又想保留编辑器提示
const data:ExpressInfo = {} as ExpressInfo

// 场景二、使用第三方库的时候缺乏对应的类型文件,或者在为”屎山“添加类型声明补充时,也是投机取巧

// 场景三、在定义object时,为object属性指定类型, 不想额外维护一个interface,也是投机取巧
const seriesData = {
	"clusterId": [] as string[],
  "clusterName": [] as string[],
  "maxTime": [] as number[]
}

获取一个已知对象的类型定义,并赋值

const optionRefType: typeof optionRef = {} as typeof optionRef;

报错:元素隐式具有 “any” 类型,因为类型为 “string” 的表达式不能用于索引类型…

// 方法一、使用Record指定key值类型
type Record<K extends string | number | symbol, T> = { [P in K]: T; }
// Construct a type with a set of properties K of type T
//example
const resourceUsageOptions:Record<string, string> = {
  name: 'CPU',
  id: '2322',
  label: 'CPU机时'
}

// 方法二、增加一个声明[key: string]: any
interface ResourceUsageOptions {
	[key: string]: any
	name: string,
  id: string,
  label: string
}

万一后端用同一个接口返回不同的实体类型…

还是可以解决的:使用联合类型声明(Union Types)

// 返回实例情况1
interface TopologyOfClusterUserInGroupRes {
	// ...
}
// 返回实例情况2
interface TopologyOfOrgRes {
	// ...
}

// 联合适配类型
type AdaptedTopologyOfClusterUserAndOrgRes = TopologyOfClusterUserInGroupRes | TopologyOfOrgRes

获取数组元素的类型

const arr = [1,2,3]

type ArrItemType= typeof arr.value[number]

AI时代-使用一个趁手的工具-CURSOR

习惯用vscode的同志们可以一键迁移扩展和配置,用起来跟vscode没什么两样,不要太苏胡!

哪里有错修哪里,不会的话,一键问AI

image.png

直接快捷键【ctrl+k】调用ai帮我出代码

image.png

在输入框中输入需求后点回车或生成按钮:

image.png

如果我们判断代码ok,那就【ctrl+回车】同意插入代码,不ok那就取消,重来

妥妥从面向百度编程转换为小助手辅助编程,爽呐~~~

最后一句忠告:不要把typeScript用成anyScript,这样不如不用呗哈哈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值