键入除 X 之外的任何数字

Bal*_*des 5 generics discriminator typescript typescript-typings

总而言之:

这种类型在 TS 中可能存在吗?Exclude<number, 200 | 400>(“除 200 或 400 之外的任何数字”)

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

type HttpResponse<Body = any, StatusCode = number> = {
  body: Body
  statusCode: StatusCode
}
Run Code Online (Sandbox Code Playgroud)

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

// 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 
Run Code Online (Sandbox Code Playgroud)

当我使用该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
}
Run Code Online (Sandbox Code Playgroud)

然而它并不是这样工作的,因为它Exclude<number, 200 | 400>与 just 相同number。我该如何解决这个问题?"any number except 200 or 400"typescript 可以实现这种类型吗?还有其他创意解决方案吗?

Ale*_*yne 6

目前这是不可能的。

请参阅: https: //github.com/microsoft/TypeScript/issues/15480


Exclude<number, 200 | 400>不起作用,因为打字稿只跟踪某物什么,而从不跟踪它不是什么。为了从无限级数中排除某些值,打字稿必须为每个可能的值生成一个并集,但您希望排除的值除外。这将是无限长度的并集(因为无穷大减 2 等于无穷大)


也就是说,http 状态代码列表实际上是有限的。因此,最好的方法可能是创建所有可能值的并集并使用它:

type HTTPStatusCode = 100 | 101 | 102 | 103 | 200 | 201 | 202 | ...
Run Code Online (Sandbox Code Playgroud)

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

Exclude<HTTPStatusCode, 200 | 400>
Run Code Online (Sandbox Code Playgroud)