TypeScript 4.9 - satisfies 操作符使用方法
TypeScript 4.9 官方版本发布链接
https://devblogs.microsoft.com/typescript/announcing-typescript-4-9-beta/#the-satisfies-operator
The new satisfies operator lets us validate that the type of an expression matches some type, without changing the resulting type of that expression.
新的 satisfies 操作符可以验证表达式的类型是否匹配某种类型,而不更改该表达式的结果类型。
这句话怎么理解呢?什么是:不改变表达式的结果类型?
/* 声明一个类型 TypeA */
interface TypeA {
amount: number | string
}
const record = {
amount: 20
} satisfies TypeA
/**
上面的写法:
既保证了 record 是符合 TypeA 类型的,
又不影响 record 的实际类型 为 :
{
amount : number
}
所以在用 record.amount.toFixed(2) 时,
不必进行强制类型转换:
const num = record.amount as number
num.toFixed(2)
**/
satisfies 可以用来捕获很多潜在的错误,确保一个对象是否符合某种数据类型(但不会改变对象本身的类型)。
正文
下面我们举例介绍 satisfies 的使用场景。
旧版本的类型匹配
在说明之前,我们先来看一个以前旧时代的类型匹配 case :
interface IConfig {
a: string | number
}
/**
* 🟡 case 1 - 以前的写法,第一行声明会报错,
* 但使用 legacy.a 时不会报错,(不报错不行,因为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
4.9 新版本的写法 :satisfies
在 TS 4.9 后,为了解决以上问题,我们应该如下编码:
interface IConfig {
a: string | number
}
/**
* 🟢 case 3 - 新写法,可以看到第一行声明会报错,
* 使用时也会报错,两全其美,很 nice
*/
const current = {} satisfies IConfig
// ^^^^^^^ 类型“{}”不满足预期类型“IConfig”。
current.a
// ^ 类型“{}”上不存在属性“a”
/**
* 🟢 case 4 - 我们基于 case 4 把值加上,
* 发现此时使用 a 的时候会自动推断我们声明的类型了!不再是联合类型。
*/
const currentWithValue = { a: 2 } satisfies IConfig
// Not error
currentWithValue.a.toFixed()
// ^ (property) a: number 🥰
TS 4.9 以后,想写 as 的时候多想想,是不是应该用 satisfies 😎 了 ?
Ref: