简体   繁体   English

在 Typescript 中,如何推断模板文字中使用的 keyof 索引访问类型

[英]In Typescript, how do I infer the keyof indexed access type used in a template literal

I have a REST api interface like this:我有一个 REST api 接口,如下所示:

interface APIs {
  artist: {
    POST: { req: TypeA, resp: TypeB}
    DELETE: { req: TypeC, resp: TypeD },
  } 
  location: {
    GET: { req: TypeE, resp: TypeF }
  }
}

That I want to convert to a set of functions like this:我想转换为一组这样的函数:

const server: Server<APIs> = {
  postArtist: (req: TypeA) => TypeB,
  deleteArtist: (req: TypeC) => TypeD,
  getLocation: (req: TypeE) => TypeF,
}

I have managed to create almost create a Server<T> type however I'm not able to reference the POST |我已经设法创建几乎创建一个Server<T>类型但是我无法引用POST | DELETE | DELETE | GET keys used in the template literal.模板文字中使用的GET键。 They appear as the key of T[Key] below so that it can be used on the right side where the ?它们在下面显示为key of T[Key] ,因此可以在右侧使用? is.是。

type Server<T> = {
  [Key in keyof T as `${Lowercase<keyof T[Key] & string>}${Capitalize<Key & string>}`]: (req: T[Key][?]) => void
}
//                                |^=How to get this=^|                            and use it here -^^

How do I reference the key that was used to generate the function name so that I can reference it on the right side.如何引用用于生成 function 名称的密钥,以便我可以在右侧引用它。

Currently in ${Lowercase<keyof T[Key] & string>}${Capitalize<Key & string>} , keyof T[Key] will be a union, and so the type expression will generate a union of keys, resulting in all sub keys being preset in the result.目前在${Lowercase<keyof T[Key] & string>}${Capitalize<Key & string>}中, keyof T[Key]会是一个并集,所以类型表达式会生成一个键的并集,导致所有结果中预设了子键。 This is a good approach if we just need the subkeys.如果我们只需要子键,这是一个很好的方法。

If we need to process each sub property individually though we should use another mapped type to produce each function individually and then merge them back into the result.如果我们需要单独处理每个子属性,尽管我们应该使用另一个映射类型来单独生成每个 function,然后将它们合并回结果中。 To merge them back into a single object we can use UnionToIntersection from here要将它们合并回单个 object 我们可以从这里使用UnionToIntersection

To extract the request and response types, the simplest solution would be to use a conditional type:要提取请求和响应类型,最简单的解决方案是使用条件类型:


interface RequestDefinition<TReq, TResp> {
    req: TReq,
    resp: TResp
}

type FromDefinition<T> = 
    T extends RequestDefinition<infer TReq, infer TResp>? (req: TReq) => TResp: never

type UnionToIntersection<U> = 
  (U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never

type Server<T> = UnionToIntersection<{
  [Key in keyof T]: {
    [Http in keyof T[Key] as `${Lowercase<Http & string>}${Capitalize<Key & string>}`]: FromDefinition<T[Key][Http]>
  }
}[keyof T]>

Playground Link 游乐场链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 TypeScript 模板文字类型 - 如何推断数字类型? - TypeScript Template Literal Type - how to infer numeric type? TypeScript:推断通用 keyof 的类型 - TypeScript: Infer type of generic keyof 打字稿:推断嵌套keyof属性的类型 - Typescript: Infer type of nested keyof Properties 在 TypeScript 中,如何推断我的参数并强加约束,即所有项都是 T 的键,其中 T 是函数的泛型类型? - In TypeScript, how can I infer my arguments and impose a constraint that all items be keyof T, where T is the generic type for the function? 包含用作接口键的 keyof 的模板文字 - Template literal containing keyof used as an interface key 如何推断记录的key<string, unknown[]> 在打字稿中</string,> - How to infer keyof Record<string, unknown[]> in TypeScript 如何在 TypeScript 中推断 object function 参数的确切类型? - How do I infer the exact type of an object function parameter in TypeScript? 为什么 Typescript 将我的 keyof 类型强制为 never 类型,我该如何解决? - Why is Typescript coercing my keyof type to a never type and how do I fix it? 声明构造函数以从TypeScript中的(keyof)参数正确推断泛型 - Declare a constructor to correctly infer generic type from (keyof) argument in TypeScript 连接两个已知字符串类型时如何推断模板文字类型 - How can I infer a template literal type when concatenating two known string types
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM