Vue3+TS

7 阅读1分钟

ts中定义参数变量类型 enum interface type有什么区别

  • 一个enum(枚举)的定义

  • 一个interface(接口)的定义

  • 一个type(类型别名)的定义

使用建议

场景

推荐使用

原因

对象结构定义

interface

可扩展、可继承、IDE 支持更好

联合/交叉类型

type

更灵活,支持复杂类型操作

固定值集合

enum

提供类型安全的值集合

函数类型

interfacetype

根据是否需要重载决定

元组类型

type

更简洁的语法

类实现

interface

明确的契约关系

工具类型

type

支持条件类型、映射类型

实际选择指南

  1. 优先使用 interface:当需要描述对象结构,且可能需要扩展时

  2. 使用 type:当需要联合类型、交叉类型或复杂类型操作时

  3. 使用 enum:当需要一组命名的常量,且这些常量在运行时需要被访问时

  4. 两者都可时:根据团队约定或个人偏好选择,保持项目一致

['','111'].filter(Boolean)是什么意思

.filter(Boolean) 用来去掉数组里的假值。

Boolean 作为回调时,会把每个元素转成布尔值:

  • 假值(falsy)→ false → 被过滤掉

  • 真值(truthy)→ true → 保留

    // 逗号分隔的字符串"tag1,,tag2,".split(',') // → ['tag1', '', 'tag2', '']// 加上 .filter(Boolean)"tag1,,tag2,".split(',').filter(Boolean) // → ['tag1', 'tag2']

等价写法

.filter(Boolean)// 等价于.filter(item => Boolean(item))// 等价于.filter(item => !!item)// 等价于.filter(item => item)

row: Record

row: Record<string, unknown> 是 TypeScript 的类型注解,用来描述 row 的类型。

含义:

Record<K, V>:TypeScript 内置工具类型,表示“键为 K、值为 V 的对象”。Record<string, unknown>:键是 string,值是 unknown 的对象。

  1. Record<K, V>:TypeScript 内置工具类型,表示“键为 K、值为 V 的对象”。
  2. Record<string, unknown>:键是 string,值是 unknown 的对象。

等价写法

// 这两种写法等价
row: Record<string, unknown>
// 等价于
row: { [key: string]: unknown }

实际含义

row 是一个对象,满足:

  1. 键:任意字符串(如 "id", "source", "name" 等)

  2. 值:任意类型(unknown 表示“类型未知,使用前需要做类型检查”)

为什么用 unknown 而不是 any?

// unknown:更安全,使用前需要先断言或收窄类型row.id  // 报错:Object is of type 'unknown'(row as TermItem).id  // 需要先断言// any:不检查,容易出错row: Record<string, any>row.id  // 不报错,但可能运行时出错

unknown 要求你在使用前显式做类型检查或断言,更安全。

在「选中/取消选中」场景里,用 Set 比用数组更合适。

1. 查找更快

// Set:O(1)
selectedIds.has(id)

// 数组:O(n)
selectedIds.includes(id)

判断某个 id 是否被选中时,Set.has() 是常数时间,数组的 includes() 需要遍历。

2. 不会重复

// Set:自动去重
selectedIds.add(1)
selectedIds.add(1)  // 不会重复
// selectedIds.size === 1

// 数组:需要手动去重
selectedIds.push(1)
selectedIds.push(1)  // 会重复
// 需要 if (!selectedIds.includes(id)) selectedIds.push(id)

Set 天然保证每个 id 只出现一次。

3. 增删更直观

// Set
selectedIds.add(id)
selectedIds.delete(id)

// 数组:需要找下标再 splice
const idx = selectedIds.indexOf(id)
if (idx > -1) selectedIds.splice(idx, 1)

4. 什么时候用数组更合适?

  • 需要保持顺序

  • 需要按索引访问

  • 需要 map、filter 等数组方法

defineEmits<{ deleted: [] }>();

defineEmits<{ deleted: [] }>() 是 Vue 3 中声明组件会发出的事件的方式。

含义

  • defineEmits:Vue 3 的编译器宏,用来定义组件会 emit 的事件。

  • <{ deleted: [] }>:TypeScript 泛型,描述事件名和参数类型。

  • deleted:事件名。

  • []:事件 payload 类型,[] 表示该事件没有参数。

等价写法

// 无参数
defineEmits<{ deleted: [] }>()

// 有参数
defineEmits<{ deleted: []; updated: [id: number, name: string] }>()

const emit = defineEmits<{ deleted: [] }>();

// 触发 deleted 事件,不传参
emit('deleted');

作用

  1. 类型检查:调用 emit('deleted', 123) 会报错,因为 deleted 定义为无参数。

  2. 文档:一眼能看出组件会发出哪些事件及参数类型。

  3. IDE 提示:能获得更准确的补全和类型提示。