Skip to main content

Command Palette

Search for a command to run...

[TS] 项目中的 Ts 使用技巧

Updated
•2 min read•View as Markdown
[TS] 项目中的 Ts 使用技巧

现在我写项目基本上都是用ts了,但是对于一些ts的机制还是比较模糊,所以写一篇博客学习一下

一些特殊类型

先来讲一讲ts中的特殊类型,有利于理解ts的类型推断

1. never 类型

never表示不存在的类型,在ts无法推断类型时,可能会将类型推断为never,例如:

type Mentor = {
  name: string,
  age: number
}
​
const mentor = reactive<Mentor>({} as Mentor)
​
/**
 * 这里的本意是 key 是 Mentor 的字段名,value 的类型是字段所对应的类型
 * 但是由于 key 的类型是联合类型,所以 key 的类型是不确定的
 * 所以此处 ts 会将 mentor[key] 推断为 never 类型
*/
const editMentor = (key: keyof Mentor, value: Mentor[typeof key]) => {
  mentor[key] // 
}

2. any 类型

在ts中,any表示任意值,所以任意的类型都可以赋值给any

使用any类型的对象时,即使使用了它身上的不存在的属性或者方法,也不会报错

类型断言 as 的使用规则

在类型为联合类型时,可以用as将其断言为更确切的类型:

let someValue: any = "this is a string"
let strLength: number = (someValue as string).length

使用as可以将类型断言为更大的类型(断言后的类型必须包括前者),但是不能断言为没有交集的类型:

type Mentor = {
  name: string,
  age: number
}
​
// 原本 mentor 的类型为 {},断言后为 Mentor,Mentor 类型包含了 {} 类型,是可以的
const mentor = reactive<Mentor>({} as Mentor)

使用 ts 为 localStorage 封装类型校验

存储localStorage时,使用getItem获取值时,默认是没有类型提示的,每次都要去看一次某个对象有什么字段,所以我们手动封装一个类,以便我们使用getItem时,有类型提示,会更方便

  • 封装一个LocalStorage类:
class LocalStorage {
  // 单例模式
  private instance: Storage
​
  constructor() {
    this.instance = window.localStorage
  }
​
  // 调用 getItem 时传入声明的类型,获取类型提示
  getItem<T>(key: string) {
    const value = this.instance.getItem(key)
    if(value) {
      const obj: T = JSON.parse(value)
      return obj
    }
    return null
  }
​
  setItem(key: string, value: any) {
    this.instance.setItem(key, JSON.stringify(value))
  }
​
  removeItem(key: string) {
    this.instance.removeItem(key)
  } 
}
​
export default LocalStorage
  • 在组件中使用:
<script setup lang="ts">
import LocalStorage from "@/utils/local-storage.ts"
import { onMounted, ref } from "vue"
​
const localStorage = new LocalStorage()
​
interface Student {
  name: string,
  age: number,
}
const student: Student = {
  name: "lordmoon",
  age: 20,
}
​
const showStu = ref<Student>()
​
onMounted(() => {
  // 调用 getItem 时传入声明的类型
  let stu = localStorage.getItem<Student>("student")
  if(!stu) {
    localStorage.setItem("student", student)
    stu = localStorage.getItem<Student>("student")
  }
  showStu.value = stu!
})
</script>
​
<template>
  <div class="container">
    <div class="name">{{ showStu?.name }}</div>
    <div class="age">{{ showStu?.age }}</div>
  </div>
</template>
​
<style lang="scss">
​
</style>

跨组件修改对象的某个字段

有时候我们会将一个对象通过props传到一个组件中,来渲染表格;如果我们想要在该组件中修改这个对象的某个字段,我们可以将你要修改的该对象的key和value传回到父组件

但是这就有一个问题,你如何确保参数的类型校验正确呢?既然都用到ts了,总不能像js那样什么类型都不校验吧

这里就可以用到ts的keyof和extends关键字了:

type Mentor = {
  name: string,
  age: number
}
​
const mentor = reactive<Mentor>({} as Mentor)
​
const editMentor = <K extends keyof Mentor> (key: K, value: Mentor[K]) => {
  mentor[key] = value
}
​
editMentor('name', 'lordmoon')
editMentor('age', 20)

More from this blog

[Vite] 处理静态资源路径

静态资源路径的种类 从路径的格式上来说,vite 的静态资源路径有两种:相对路径 和 绝对路径 从路径的类型上来说,vite 的静态资源路径有两种:基于 http URL 的 和 基于文件系统的 相对路径 在 vite 文档的表述中,相对路径常用于在 “嵌入式” 的页面中使用: 这里的 “嵌入式” 指的是例如浏览器插件这种,将一个页面嵌入到一个网页中的形式 绝对路径 绝对路径指的是 “以根路径为起点” 而表示的路径 绝对路径在 “基于 http URL” 和 “基于文件系统” 的情况下,最终表...

Oct 2, 20251 min read

[Node] Mac m 芯片使用 node 14

最近在 m 芯片的 mac 电脑上使用 node 14 版本,遇到了芯片架构不兼容的错误,所以记录一下解决问题的过程 遇到的问题 原因是 node 14 版本只支持 x86_64 架构的芯片,所以使用 arm 架构的 m 芯片就会报错 解决方案 前置知识 在 m 芯片的 mac 上,node 16 及以上的版本全面支持了 arm 芯片架构;如果要安装 16 以下的版本,需要通过 Rosetta 2 转译执行 步骤 按照 nvm 官方的步骤进行:https://github.com/nvm-sh/...

Jul 11, 20251 min read
[Node] Mac m 芯片使用 node 14

[其他] WSL Interop

最近在 wsl 下使用 code <dir> 命令拉起 windows 下的 vscode 客户端时,遇到了错误,搜了一下发现是 wsl 和 windows 的互操作出现了问题 这篇文章就来记录一下遇到的问题和相关的知识点 WSLInterop.conf 文件 WSLInterop.conf 文件是 WSL(Windows Subsystem for Linux)中的一个关键配置文件,它定义了 Linux 系统如何识别和处理 Windows 可执行文件 文件位置和基本作用 这个文件通常位于 /u...

Jul 11, 20252 min read
[其他] WSL Interop

lordmoon's blog

25 posts