打字稿除 X 以外的任何数字

Posted

技术标签:

【中文标题】打字稿除 X 以外的任何数字【英文标题】:Typescript any number except X 【发布时间】:2021-09-01 15:04:00 【问题描述】:

TLDR:

这种类型在 TS 中是否可行? Exclude<number, 200 | 400>(“除 200 或 400 以外的任何数字”)

我有以下用例。我有一个响应类型,它是通用的:

type HttpResponse<Body = any, StatusCode = number> = 
  body: Body
  statusCode: StatusCode

我想使用状态码作为鉴别器:

// Succes
type SuccessResponse = HttpResponse<SomeType, 200>
// Known error
type ClientErrorResponse = HttpResponse<ClientError, 400>
// Anything else, generic error, issue is with the status code here.
type OtherErrorResponse = HttpResponse<GenericError, Exclude<number, 200 | 400>>

// The response type is a union of the above
type MyResponse = SuccessResponse | ClientErrorResponse | OtherErrorResponse 

当我使用MyResponse 类型时,我想使用状态码作为鉴别器,例如:

const response: MyResponse = ...

if(response.statusCode === 200) 
  // response is inferred as SuccessResponse => body is inferred as SomeType
 else if(response.statusCode === 400) 
  // response is inferred as ClientErrorResponse => body is inferred as ClientError
 else 
  // response is inferred as OtherErrorResponse => body is inferred as GenericError

但是它不能像这样工作,因为Exclude&lt;number, 200 | 400&gt;number 相同。我该如何解决这个问题?打字稿可以使用"any number except 200 or 400" 类型吗?还有其他创意解决方案吗?

【问题讨论】:

【参考方案1】:

目前这是不可能的。

见:https://github.com/microsoft/TypeScript/issues/15480


Exclude&lt;number, 200 | 400&gt; 不起作用,因为 typescript 只跟踪 是什么,从不跟踪 不是。为了使从无限系列中排除某些值,打字稿必须为每个可能的值生成一个联合,除了您希望排除的值。这将是一个无限长的并集(因为 Infinity - 2 等于 Infinity)


也就是说,http 状态码列表实际上是有限的。所以最好的方法可能是创建一个所有可能值的联合并使用它:

type HTTPStatusCode = 100 | 101 | 102 | 103 | 200 | 201 | 202 | ...

现在应该可以正常工作了:

Exclude<HTTPStatusCode, 200 | 400>

【讨论】:

以上是关于打字稿除 X 以外的任何数字的主要内容,如果未能解决你的问题,请参考以下文章

打字稿和传播运算符?

Visual Studio 2015 中的打字稿

打字稿在编译时减去两个数字

打字稿:具有有效打字的“找不到模块”

如何在打字稿接口/类型中将枚举值类型转换为数组?

在打字稿中,如何检查字符串是不是为数字