记录一次使用mitt库后了解到的type和interface异同

起因是在初始化mitt实例时,发现如果传入interface作为泛型时会抛出异常:

类型"Events"不满足约束"Record<EventType, unknown>"。

类型"Events"中缺少类型"string"的索引签名。ts(2344)。

于是去看了一下传入的泛型Event 的定义:

typescript 复制代码
export declare type EventType = string | symbol;
//  ...
export default function mitt<Events extends Record<EventType, unknown>>(all?: EventHandlerMap<Events>): Emitter<Events>;

这里mitt对传入的泛型Events用extends关键字做了个约束,要求Events必须满足Record<EventType, unknown>,也就是说Events必须是一个键为字符串字面量,值为unknown的Record类型。

其中type有隐式索引签名(implicit index signature)Record<PropertyKey, unknown> 自动满足条件,但是interface是一种静态的类型声明,它并没有隐式索引签名,因此会抛出异常,如果需要使用interface,需要手动添加索引签名:

typescript 复制代码
interface Events {
	// ...
	[key: string | symbol]: unknown
}

但是如果这样写的话,会出现以下问题:

  • 接口就的类型约束就被破坏了,key可以是任意的字符串,无法确保事件的key是上面编写的字符串字面量;
  • 接口可以被任意扩展,可能添加非法事件;
  • 无法利用类型系统进行静态检查。
typescript 复制代码
interface Events {
  // ...
}

interface Events {
  [key: number]: string // 新增了数字key
}

为什么mitt要用Record<EventType, unknown>来做限制而不是Record<EventType, any>:

unknown 和 any 虽然都代表"不确定的类型",但它们在类型安全性上有着本质区别:

  1. unknown 是类型安全的顶级类型

    • 它是 TypeScript 3.0 引入的类型安全的"任意值"表示
    • 任何值都可以赋给 unknown 类型变量
    • 但在使用前必须进行类型检查或类型断言
  2. any 是类型系统的逃生舱

    • 它会完全绕过 TypeScript 的类型检查
    • 可以对其执行任何操作而不触发类型错误
    • 相当于回到了纯 JavaScript 的开发模式

参考资料:

www.totaltypescript.com/type-vs-int...

相关推荐
螺丝钉tina5 小时前
[Playwright][01] 从 Puppeteer 到 Playwright:为什么选择 Playwright + TypeScript?
前端·javascript·typescript
miofly19 小时前
GitHub 今日推荐|rea:用 MCP 把反编译器和 AI agent 接到一起的逆向工具
typescript·开源·github
ZoeLandia1 天前
React11:数据请求与 TanStack Query
前端·react.js·typescript·react
康小旺2 天前
AI 写 Vue 总写成同一个味道:给它装 Skills,装的不是知识是边界
vue.js·typescript
ZoeLandia2 天前
React08:自定义 Hook
开发语言·前端·react.js·typescript
aloha_7893 天前
HTML、JavaScript 与 TypeScript 基础速查
javascript·typescript·html
离歌漠4 天前
《我用 Tauri 做了一个本地开发工具箱》
rust·typescript·vue
enjoy编程4 天前
playwright学习-I
typescript·vue·nodejs·1024程序员节·playwright
iDao技术魔方4 天前
Bun v1.4.4 实战:用 bun fmt 替掉 prettier 的 5 个步骤
typescript·1024程序员节
梅雅达编程笔记4 天前
Day 17 | uni-app 小程序:前端从零搭建
微信小程序·typescript·uni-app·vue3·pinia·前端开发·全栈