简体   繁体   English

Typescript 基于同级字符串字段的 Object 键的动态类型

[英]Typescript Dynamic type for Object key based on sibling string field

i am trying to create a dynamic type based on parts of a sibling 'string type:我正在尝试基于兄弟字符串类型的部分创建动态类型:

example例子

function getDynamicRoutes(href: string) {
  return (
    href
      .match(/:([A-z]*)/gm)
      .map(s => s.replace(':', ''))
      .reduce((a, c) => ({ ...a, [c]: true }), {})
  )
} 

interface Props {
  // foo/:bar/helloworld/:bat
  href: string;
  
  // { bar: 'string', bat: 'string' }
  substitutes: {
    [k: keyof getDynamicRoutes(Props['href'])]: string;
  }
}

expected behaviour When i provide the above href i should get auto-typing for the substitutes Object based on the colon-prepended routes in the href.预期行为 当我提供上述href时,我应该根据 href 中的冒号前缀路由自动输入替代品 Object。

So: 'foo/:bar/helloworld/:bat' Will generate a type interface for substitutes as: { bar: 'string', bat: 'string' }所以: 'foo/:bar/helloworld/:bat'将为substitutes生成一个类型接口: { bar: 'string', bat: 'string' }

Is this possible?这可能吗?

You are not allowed to call getDynamicRoutes inside interface definition.不允许在接口定义内调用getDynamicRoutes Furthermore, it is either disallowed to pass Props['href'] type alias as a function argument.此外,不允许将 Props['href'] 类型别名作为 function 参数传递。 In general you can't use types where values are expected.通常,您不能在需要值的地方使用类型。 If you want to map query string to interface you can do this:如果你想 map 查询字符串接口你可以这样做:

const handle = <Query extends string>(str: Query): ToType<Query> => {
    // implementation is up to You :)
    return null as any
}

type ToType<T extends string, Cache extends Record<string, string> = {}> =
    T extends `${string}/:${infer Prop}/${infer Rest}`
    ? ToType<Rest, Cache & Record<Prop, string>>
    : T extends `${string}/:${infer Last}`
    ? Cache & Record<Last, string>
    : never


// Record<"bar", string> & Record<"bat", string>
const result = handle('foo/:bar/helloworld/:bat')

Playground 操场

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM