浅析TypeScript 4.9 satisfies操作符使用方法

前言

TypeScript 4.9 将新增 satisfies 操作符,类似于 as ,但他更像一个不那么 strictas

正文

下面我们举例介绍 satisfies 的使用场景。

旧时代的类型匹配

在说明之前,我们先来看一个以前旧时代的类型匹配 case :

interface IConfig {
  a: string | number
}

/**
 * 🟡 case 1 - 以前的写法,第一行声明会报错,但使用 legacy.a 时不会报错,这是有问题的
 */
const legacy: IConfig = {}
//    ^^^^^^ 类型 "{}" 中缺少属性 "a",但类型 "IConfig" 中需要该属性。
legacy.a 
//     ^ (property) IConfig.a: string | number

/**
 * 🔴 case 2 - 以前的另一种写法,声明和使用都不会报错,大错特错!
 */
const legacyAs = {} as IConfig
// Not error
legacyAs.a
//       ^ (property) IConfig.a: string | number
小结

case 1case 2 💩 一样的写法以前我们都可能用到,很多时候,我们明知道 case 2 是大错特错的,但是我们不想把这个 对象 给提取出来了,所以就直接写了 as ,这是万万不可取的。

旧时代的改进与解法

既然旧时代的两种写法都有问题,我们如何解 ?

interface IConfig {
  a: string | number
}

/**
 * 🟡 case 3 - 我们知道 case 2 大错特错,所以我们就基于 case 1 来编写,但是 `a` 的类型推断不出来
 *             那么,我们为了有类型提示,只能多写一步 as 了。
 */
const legacyWithValue: IConfig = { a: 2 }
// Not error
legacyWithValue.a.toFixed()
//                ^^^^^^^ 类型“string | number”上不存在属性“toFixed”
;(legacyWithValue.a as number).toFixed()
// Not error        ^^ 🤮
小结

case 3 的写法在以前应该是最好的写法了,就是 先声明,再 as ,和个小丑 🤡 一样,那有没有更好的写法?

新时代的写法 :satisfies

在 TS 4.9 后,为了解决以上问题,我们应该如下编码:

interface IConfig {
  a: string | number
}

/**
 * 🟢 case 4 - 新写法,可以看到第一行声明会报错,使用时也会报错,两全其美,很 nice 
 */
const current = {} satisfies IConfig
//                           ^^^^^^^ 类型“{}”不满足预期类型“IConfig”。
current.a
//      ^ 类型“{}”上不存在属性“a”

/**
 * 🟢 case 5 - 我们基于 case 4 把值加上,发现此时使用 a 的时候会自动推断我们声明的类型了!不再是联合类型。
 */
const currentWithValue = { a: 2 } satisfies IConfig
// Not error
currentWithValue.a.toFixed()
//               ^ (property) a: number 🥰
小结

TS 4.9 以后,想写 as 的时候多想想,是不是应该用 satisfies 😎 了 ?

总结

satisfies 可以非常丝滑的解决 对象 的格式匹配问题,关于更多信息,请参见 Announcing TypeScript 4.9 Beta

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值