【问题标题】:Nested keyof object paths (using dot notation) [duplicate]嵌套 keyof 对象路径(使用点表示法)[重复]
【发布时间】:2018-01-06 23:58:51
【问题描述】:

我正在寻找嵌套对象路径:这样的事情可能吗?

interface IHuman {
    age: number;
    friend: {
        name: string;
    }
}

keyof IHuman; // "age", "friend.name"

【问题讨论】:

  • 不是在编译时,没有...
  • 我已经关闭了这个问题,因为它已经过时了;可以在here找到更新的答案。

标签: typescript


【解决方案1】:
type AnyObject = Record<string, any>

type DotJoin<A extends string, B extends string> = A extends '' ? B : `${A}.${B}`

type DeepKeys<O extends AnyObject> = {
  [K in keyof O]: O[K] extends AnyObject ? K : never
}[keyof O]

// @ts-expect-error Type 'keyof O' does not satisfy the constraint 'string'.
type DotBranch<O extends AnyObject, P extends string = '', K extends string = keyof O> =
  K extends DeepKeys<O>
  ? DotBranch<O[K], DotJoin<P, K>>
  : /*************/ DotJoin<P, K>
interface Obj {
  a: {
    x: string
    y: {
      z: string
    }
  }
  b: {
    u: boolean
  }
  c: number
}

type D = DotBranch<Obj> // type D = "c" | "a.x" | "a.y.z" | "b.u"

declare function get(path: DotBranch<Obj>)
get('') // Argument of type '""' is not assignable to parameter of type '"c" | "a.x" | "a.y.z" | "b.u"'.

Typescript Playground
GitHub Gist

【讨论】:

    【解决方案2】:

    我觉得这不可能,至于为什么我可以胡乱猜测:

    interface IHuman {
        age: number;
        'friend.name': any;
        friend: {
            name: string;
        }
    }
    
    const b: keyof IHuman = 'friend.name';
    

    friend.name 现在会模棱两可。

    【讨论】:

      【解决方案3】:

      我也没有找到一个很好的解决方案。 但是您可能想看看 typed-path 项目。

      【讨论】:

        【解决方案4】:

        这是不可能的,因为 TypeScript 中没有 string literal type operators。给定字符串文字 "foo""bar",没有编程方法可以从类型 systm 中获取字符串文字 "foo.bar"。 GitHub 中提交了一些功能建议,如果实施,它们可能会实现这一点,例如 key augmentationregular-expression string validation。但看起来他们并没有被积极研究。

        【讨论】:

        猜你喜欢
        • 2018-02-08
        • 1970-01-01
        • 1970-01-01
        • 2016-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-06
        • 1970-01-01
        相关资源
        最近更新 更多