[英]Type-checking correct key-value usage in a returned object
我有一个可能的响应主体的(生成的)类型定义:
type ResponseMap = {
'200': { 'ok': true },
'404': { 'error': true, type: 'NotFound' },
'500': null,
}
我想编写一个函数,该函数将返回{ code, body }
形状的对象,并根据上面的输入进行检查。
我能够完成的最好的事情如下:
type Codes<Bodies> = keyof Bodies
type ResponseCodeBodyPair<Bodies extends Record<string, unknown>> = {
code: Codes<Bodies>,
body: Bodies[Codes<Bodies>]
}
function endpoint(): ResponseCodeBodyPair<ResponseMap> {
if (Math.random()) {
return { code: '200', body: { 'ok': true } }
}
if (Math.random()) {
return { code: '404', body: { 'error': true, type: 'NotFound' } }
}
if (Math.random()) {
return { code: '500', body: null }
}
// This should fail since { ok: true } is not a valid body for 404.
return { code: '404', body: { 'ok': true } }
}
此检查是否有函数返回的未知状态代码以及所有返回的主体是否与可能的主体形状之一对应。
它不检查代码到正文配对的正确性,如上次返回所示。
如何将类型限制为状态代码的精确体型?
我需要类似的东西
type ResponseCodeBodyPair<Bodies extends Record<string, unknown>> =
Code extends keyof Bodies ? { code: Code, body: Bodies[Code] } : never
……但这当然行不通。
我在同样的情况下挣扎了很多次,但总是放弃。 它实际上是不可能的还是我错过了什么?
PS 我知道如果类型是{ code: '200', body: … } | { code: '404', … } | …
{ code: '200', body: … } | { code: '404', … } | …
{ code: '200', body: … } | { code: '404', … } | …
但我没有那个。 这就是为什么我需要以某种方式将地图/记录转换为这种联合类型。
我发现了正确的方法来做到这一点。
我可以将{ [Code]: Response }
对象映射到{ [Code]: { code: Code, body: Response } }
对象,并通过T[keyof T]
该对象的值,从而得到准确的类型 I需要。
type ResponseCodeBodyPairMap<M> = {
[Code in keyof M]: { code: Code, body: M[Code] }
}
type Values<T> = T[keyof T]
type ResponseCodeBodyPair<M> = Values<ResponseCodeBodyPairMap<M>>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.