Typescript 4.5 中模板字符串类型作为判别式
Typescript 4.5 刚刚发布,其中最让我印象深刻的功能之一就是模板字符串类型作为判别式。在本文中,我们将通过一些基本示例来探索这一新功能。在我的上一篇文章中,我们介绍了如何使用判别联合来编写更易于缩小的类型。
这是对此的扩展,但不是使用具体的文字类型,而是可以使用非具体的文字类型(即字符串,数字等)作为模板文字类型的一部分,并且 Typescript 将能够使用它作为判别式。
为了理解此功能,我们将首先创建两种类型:SuccessType
和ErrorType
。它们将代表我们在计算机系统中可以执行的不同操作的可能响应,例如 HTTP 请求、FTP 请求、IO 请求等。因此,如果 HTTP 请求成功,我们将获得SuccessType
数据;如果失败,我们将获得ErrorType
数据。
这两种类型各自都有一个type
属性,当它们在联合体中使用时,我们可以使用该属性来区分它们ResponseType
。但我们不会使用具体的字面量类型,而是使用模板字符串类型。
这意味着生成的模板字面量类型可以是任何与Success
或组合的字符串,Error
即${string}Success
和${string}Error
。这将使我们的成功类型能够涵盖许多可能的操作,例如httpSuccess
、ftpSuccess
等,对于 也同样如此ErrorType
。
type SuccessType = {
type: `${string}Success`,
data: Record<string, unknown>;
}
type ErrorType = {
type: `${string}Error`,
message: string;
}
type ResponseType = SuccessType | ErrorType;
function processHTTPResponse(response: ResponseType) {
// function body here
}
在以前的版本中,Typescript 无法ResponseType
根据类型字段缩小联合的类型,如下所示。
但从最新版本(4.5 及以上版本)开始,typescript 能够将的类型缩小response
到SuccessType
如下所示。
可以想象,通过提供一种非具体的字面类型,TypeScript 可以区分两个并集,只要用于区分的字段包含在被比较的字符串中即可。以下是另一个简单的例子:
type HttpOK = {
status: `2${string}`;
data: string;
}
type Http500 = {
status: `5${number}`;
message: string;
}
type Http300 = {
status: `3${string}`;
redirect: string;
}
function processResponse(response: HttpOK | Http300 | Http500) {
if(response.status === "200") {
console.log(response.data);
}
if(response.status === "300") {
console.log(response.redirect);
}
if(response.status === "500") {
console.log(response.message);
}
}
这是上述代码的Typescript Playground链接。
结论
在这篇简短的文章中,我们介绍了 Typescript v4.5 中即将推出的一项新功能:使用模板字符串类型作为判别式。这使我们能够通过依赖判别式属性的模板模式(而不是精确的字符串)来构建更通用的类型。
链接:https://dev.to/this-is-learning/template-string-types-as-discriminants-in-typescript-45-4fdi