TypeScript使用记录

lishihuan大约 3 分钟

TypeScript使用记录

非空断言&可选链

  • item!.id:非空断言 (明确item是一定存在,也即是不会出现nullundefined 的情况,这样使用是告知编译器不要进行空值检查)

  • item?.id可选链(不明确item是否为空的情况下使用,否则可能会报错)

  1. 非空断言 (item!.id):
    • item! 是一个非空断言,表示你告诉 TypeScript 编译器 item 在这里不会是 nullundefined
    • 使用非空断言后,编译器会假设 item 一定存在,因此可以安全地访问 id 属性,而不会进行空值检查。
    • 如果 item 实际上为 nullundefined,使用非空断言将会导致运行时错误。
  2. 可选链 (item?.id):
    • item?.id 使用了可选链操作符 ?.,这是一种安全地访问深层属性的方式。
    • 如果 itemnullundefined,表达式将短路返回 undefined,而不会抛出错误。
    • 可选链允许你访问可能不存在的属性,而不会中断整个表达式。

可选链操作符 ?. 通常用于当你不确定对象是否存在时,它提供了一种优雅的方式来避免运行时错误。而非空断言 ! 则是一种断言,表示你确信某个位置的值不会是 nullundefined,通常用于你已经通过其他方式验证了值的存在性。

两者的主要区别在于:

  • 非空断言 (!) 强制 TypeScript 编译器忽略空值检查,但要求开发者对值的存在性负责。
  • 可选链 (?.) 允许 TypeScript 在运行时安全地处理可能的空值,无需额外的空值检查。

在实际编码中,你应该根据上下文和你对值存在性的了解来选择使用非空断言还是可选链。

<script setup lang="ts">
    const profile = ref<ProfileDetail>({})
</script>
<template>
	<image class="image" :src="profile.avatar" mode="aspectFill" />
</template>

如果初始定义类型的时候,没指定类型,则使用 profile.avatar 会报错,需要使用 可选链 profile?.avatar

<script setup lang="ts">
    const profile = ref<ProfileDetail>()
</script>
<template>
	<image class="image" :src="profile?.avatar" mode="aspectFill" />
</template>
const profile = ref({} as ProfileDetail) // {} as ProfileDetail 用断言的方式 给profile 对象设置一个初始值

2. 交叉类型合并

将多个类型合并为一个类型

interface Name {
  name: string;
}

interface Age {
  age: number;
}

// 创建一个交叉类型,它包含了 Name 和 Age 接口的所有属性
type Person = Name & Age;
// 或者直接这样合并
type Person2 = Name & {
    age: number;
};
// 使用 Person 类型
const person: Person = {
  name: '张三',
  age: 30
};


Pick的使用

  1. Pick:从 ProfileDetail 类型中选取指定的属性('nickname''gender''birthday''profession')创建一个新的类型。
  2. 然后通过 & 与一个包含可选属性(provinceCodecityCodecountyCode)的对象进行交叉类型合并,最终得到 ProfileParams 类型,该类型包含了选取的属性以及可选的编码属性。
/** 个人信息 用户详情信息 */
export type ProfileDetail = {
  /** 性别 */
  gender?: Gender
  /** 生日 */
  birthday?: string
  /** 省市区 */
  fullLocation?: string
  /** 职业 */
  profession?: string
}

/** 个人信息 修改请求体参数 */
export type ProfileParams = Pick<
  ProfileDetail,
  'nickname' | 'gender' | 'birthday' | 'profession'
> & {
  /** 省份编码 */
  provinceCode?: string
  /** 城市编码 */
  cityCode?: string
  /** 区/县编码 */
  countyCode?: string
}