TypeScript 系列:satisfies 的实用之处

假设我们要定义一份配置,如果直接写则没有类型提示,写错字段名或少写字段 TS 也不会报错。

ts 复制代码
const TIME_UNITS_TRANSLATIONS = {
    day: {
        singular: 'day',
        plural: 'days',
    },
    hour: {
        singular: 'hour',
        plural: 'hours',
    },
    minute: {
        singular: 'minute',
        plural: 'minutes',
    },
    second: {
        singular: 'second',
        plural: 'seconds',
    },
    millisecond: {
        singular: 'millisecond',
        plural: 'milliseconds',
    },
}

但若加上类型,确实解决了字段提示的问题,但是又会出现新问题:

ts 复制代码
type ITimeUnit = 'day' | 'hour' | 'minute' | 'second' | 'millisecond'
type IForms = {
    singular: string
    plural: string
}

const TIME_UNITS_TRANSLATIONS: Record<ITimeUnit, IForms> = {
    day: {
        singular: 'day',
        plural: 'days',
    },
    hour: {
        singular: 'hour',
        plural: 'hours',
    },
    minute: {
        singular: 'minute',
        plural: 'minutes',
    },
    second: {
        singular: 'second',
        plural: 'seconds',
    },
    millisecond: {
        singular: 'millisecond',
        plural: 'milliseconds',
    },
}

当我们 hover 变量其类型变成

const TIME_UNITS_TRANSLATIONS: Record<ITimeUnit, IForms>

而不加类型之前,VSCode 是能完整提示到字段级别的。这样便于我们观察变量,无需跳转到其定义处就能知道里面有哪些字段。

ts 复制代码
const TIME_UNITS_TRANSLATIONS: {  
    day: {  
        singular: string;  
        plural: string;  
    };  
    hour: {  
        singular: string;  
        plural: string;  
    };  
    minute: {  
        singular: string;  
        plural: string;  
    };  
    second: {  
        singular: string;  
        plural: string;  
    };  
    millisecond: {  
        singular: string;  
        plural: string;  
    };  
}

能否一举两得 - satisfies to the rescue 💉

ts 复制代码
const TIME_UNITS_TRANSLATIONS = {
    day: {
        singular: 'day',
        plural: 'days',
    },
    hour: {
        singular: 'hour',
        plural: 'hours',
    },
    minute: {
        singular: 'minute',
        plural: 'minutes',
    },
    second: {
        singular: 'second',
        plural: 'seconds',
    },
    millisecond: {
        singular: 'millisecond',
        plural: 'milliseconds',
    },
} satisfies Record<ITimeUnit, IForms>

这时候 hover 后发现我们平铺的类型定义又回来,而且字段能自动提示。

更进一步 - as const satisfies ... 🔬

能否做到更好?我们试试 as const satisfies ...

ts 复制代码
const TIME_UNITS_TRANSLATIONS = {
    day: {
        singular: 'day',
        plural: 'days',
    },
    hour: {
        singular: 'hour',
        plural: 'hours',
    },
    minute: {
        singular: 'minute',
        plural: 'minutes',
    },
    second: {
        singular: 'second',
        plural: 'seconds',
    },
    millisecond: {
        singular: 'millisecond',
        plural: 'milliseconds',
    },
} as const satisfies Record<ITimeUnit, IForms>

此时发现还能具体到字段的值,完美!

第二个例子

这个例子帮助我们更好理解 satisifies

ts 复制代码
type User = {
  id: string;
  name: string;
  age?: number;
};

const alice = {
  id: "123",
  name: "Alice",
  age: 30,
} satisfies User; // ✅ 类型仍然是 { id: string; name: string; age: number }

// 仍然可以访问 alice.age.toFixed(2),因为 age 被推断为 `number` 而不是 `number | undefined`

如果改成普通的类型标注:

ts 复制代码
const alice: User = {
  id: "123",
  name: "Alice",
  age: 30,
}; // 类型变成了 User 即 { id: string; name: string; age?: number }

alice.age.toFixed(2)
// ^^^^ 'alice.age' is possibly 'undefined'.(18048)

代码将报错因为 age 被推断为number | undefined 而不是 number

但实际上我们知道 alice 的 age 并不为空(30)。

到这里我们就学会了何时在项目中使用 satisifies 了 🎉!

总结

当我们想验证变量类型但不改变类型本身 ,可以试试 satisifies,打破鱼与熊掌二者不可兼得。

参考

相关推荐
柯克七七2 小时前
我把 bug 修得太干净了,测试组以为这个模块本来就没问题
前端·javascript·typescript
退休倒计时3 小时前
【每日一题】LeetCode 39. 组合总和 TypeScript
算法·leetcode·typescript
yyt3630458414 小时前
KlineChartQuant Tooltip 高频交互 200FPS 性能优化完整复盘
前端·经验分享·性能优化·typescript·vue·交互·chrome devtools
用户0934077735149 小时前
HarmonyOS WPS Open SDK 实践:办公审批附件「打开—编辑—回传」代码实现
typescript·harmonyos
Flynt9 小时前
TypeScript 5.8 让我少踩了一个大坑,顺手再聊聊 --erasableSyntaxOnly
前端·javascript·typescript
退休倒计时1 天前
【每日一题】LeetCode 17. 电话号码的字母组合 TypeScript
算法·leetcode·typescript
无情的西瓜皮2 天前
MCP 协议实战:从零搭建一个 MCP 服务器(Node.js 版)
vue.js·人工智能·typescript·node.js
退休倒计时2 天前
【每日一题】LeetCode 78. 子集 TypeScript
算法·leetcode·typescript
学习-学习2 天前
Node.js 现在能直接跑 TypeScript 了?Type Stripping 原理、限制与 tsx / ts-node 取舍
typescript·node.js
yume_sibai3 天前
大屏数据可视化 - 边框红绿呼吸灯实现详解
前端·信息可视化·typescript