TypeScript 在项目的使用

2023/04/10 文章推荐 共 3625 字,约 11 分钟

TypeScript 大家都不陌生,在项目中都用过,基础用法也很简单。任何一个东西如果要用好,还是需要花一点时间去研究一下。

相似类型区别与联系

interface 常用于定义对象或者类的类型,可以被继承和实现,可以重命名定义,会自动合并同名的属性

type 常用于定义基本类型,复杂类型,联合类型,泛型等

interface 与 type 的区别有下面几点。 (1)type能够表示非对象类型,而interface只能表示对象类型(包括数组、函数等)。 (2)interface可以继承其他类型,type不支持继承。 继承的主要作用是添加属性,type定义的对象类型如果想要添加属性,只能使用&运算符,重新定义一个类型。

any 和 unknown 都是用来表示不确定类型的关键字,使用 unknown 类型声明的变量被认为是一个安全的类型,无法直接赋值给其他的类型变量,只有进行了类型检查之后才能进行类型转换,而使用 any 类型可以直接赋值给其他类型变量,但可能会出现运行时类型错误。(any:霍霍别人, unknow:只霍霍自己)

! 和 ?

!是一个后缀操作符,则用于在某些情况下,表示该属性或参数一定会有值

let element = document.getElementById("myElement")!;
element.innerHTML = "Hello, World!"

?用于属性或参数名称后,表示该属性或参数是可选的

interface Obj<Type>{
  name:Type
  age?:number
}
const ob :Obj<number>={
  name:0,
}

as 类型断言操作符,用于在编译器中指定类型。使用!可能会导致运行时错误,因为它强制去除了null和undefined,而as 就是明确指定了类型,都需要谨慎使用

enum 枚举类型预先确定好的常量集合,为其取一个易于理解的名字

?? 运算符来检查变量是否未定义或 null,未定义的时候后面的参数即提供默认值。

never 和void的区别

never 不可能有这样的值,所以他可以赋值给任意其他类型

void 表示没有返回值的函数类型或者变量

泛型

通过参数来定义特定的类型(带有类型参数),比如说函数调用的时候需要提供类型参数,axios响应的时候,data的值 自定义简单泛型

interface Obj<Type>{
  name:Type
}
const obj :Obj<number>={
  name:0,
}

自定义继承泛型

function getName<Type>(param:Type):Type{
  return param
}
function getData<Type extends {length:number}>(param:Type):string{
  if(param.length){
    return 'param has length'
  }else{
    return `param no length`
  }
}
function combine<Type>(arr1:Type[],arr2:Type[]):Type[]{
  return arr1.concat(arr2)
}
const arr = combine<number|string>([1,2,3],['hell'])

infer 关键字: 定义泛型里面推断出来的类型参数,而不是外部传入的类型参数

例如:Flatten 是不是一个数组,是的话就返回数组的每一项,不是的的话,就返回自身

type Flatten<Type> = Type extends Array<infer Item> ? Item : Type
等同于下面这句
 type Flatten<Type,Item> = Type extends Array<Item> ? Item:Type

typeof 类型操作符,获取某个值/变量/函数/表达式的类型

GreeType 被推断为函数类型

function greet(name:string):string{
  return `hello ${name}`
}
type GreeType = typeof greet  

typeof 只能获取类型信息,不能实例化一个对象或者函数,如果要获取一个实例类型需要配合InstanceType 一起使用

ReturnType 是一个内置的工具类型,用于获取函数返回值的类型

function f() {
  return { x: 10, y: 3 };
}
type P = ReturnType<typeof f>;

它需要使用 typeof 操作符来获取函数类型。这是因为只有这样才能保证传递给 ReturnType 的类型参数是正确的。

如果不使用 typeof 操作符,而是直接传递一个函数名作为参数,直接报错,需要使用一个类型

InstanceType 是一个内置的工具类型,它可以用于获取实例类型

class Person {
  name: string;
  age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}
type PersonType = InstanceType<typeof Person>;

PersonType 将被推断为 Person 类型,因为它使用了 Person 类的构造函数类型。

需要注意的是,typeof 更加通用,可以用于获取任何类型的静态信息

InstanceType 则更加专注于获取复杂类型的实例类型信息。

在实践中,两种类型工具可以共同使用,例如,在某些使用场景下,可以结合使用 typeof 和 InstanceType 来获取类型信息以增加代码的可读性和可维护性。

例如在vue中获取组件类型

<!-- App.vue -->
<script setup lang="ts">
import MyModal from './MyModal.vue'

const modal = ref<InstanceType<typeof MyModal> | null>(null)

const openModal = () => {
  modal.value?.open()
}
</script>

其他类型

Pick从Type类型中选择一组属性键

interface Todo {
  title: string;
  descriptipn: string;
  name:string
  age:number
}
type TodoPreview = Pick<Todo, "title" | "descriptipn"|"age">;

Omit 从 Type 中选择所有属性然后删除键

type TodoPreview1 = Omit<Todo,'age'|'name'>

Record<Keys, Type> : 对象类型,其属性键为 Keys,其属性值为 Type。该实用程序可用于将一种类型的属性映射到另一种类型。

interface CatInfo {
  age: number;
  breed: string;
}
 
type CatName = "miffy" | "boris" | "mordred";
 
const cats: Record<CatName, CatInfo> = {
  miffy: { age: 10, breed: "Persian" },
  boris: { age: 5, breed: "Maine Coon" },
  mordred: { age: 16, breed: "British Shorthair" },
};

// 等价于
export interface Item {
  [key: string]: {
    id: string 
  }
}
const ca: Item = {
  name:{
    id:'9090'
  }
}

DOM 中使用到的一些类型

FileList 类型

const fileList: FileList | null = (ev.target as HTMLInputElement).files

FileReader 类型

let reader: FileReader | null = new FileReader()

FileReader 流类型

reader.onload = (e: ProgressEvent<FileReader>) => {}

FormData 类型

const params:FormData = new FormData()

HTMLImageElement 类型

let image: HTMLImageElement | null = new Image()

类数组转换数组类型

Array.from(fileList as FileList)

as 在 DOM 中的使用

(document.getElementById('waterMarkUploadID') as HTMLInputElement).value = “”

const { width, height } = image as HTMLImageElement


在技术的历史长河中,虽然我们素未谋面,却已相识已久,很微妙也很知足。互联网让世界变得更小,你我之间更近。

在逝去的青葱岁月中,虽然我们未曾相遇,却共同经历着一样的情愫。谁的青春不曾迷茫或焦虑亦是无奈,谁不曾年少过

在未来的日子里,让我们共享好的文章,共同学习进步。有不错的文章记得分享给我,我不会写好的文章,所以我只能做一个搬运工

我叫 sunseekers(张敏) ,千千万万个张敏与你同在,18年电子商务专业毕业,毕业后在前端搬砖

如果喜欢我的话,恰巧我也喜欢你的话,让我们手拉手,肩并肩共同前行,相互学习,互相鼓励

文档信息

Search

    Table of Contents