嵌套的keyof对象路径(使用点表示法)

时间:2017-07-31 12:02:40

标签: typescript

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

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

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

4 个答案:

答案 0 :(得分:1)

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

The main idea of this project in a single image

答案 1 :(得分: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 :(得分:0)

我不认为这是可能的,至于为什么我可以猜测:

interface IHuman {
    age: number;
    'friend.name': any;
    friend: {
        name: string;
    }
}

const b: keyof IHuman = 'friend.name';

friend.name现在会变得暧昧。

答案 3 :(得分:0)

这是不可能的,因为TypeScript中没有string literal type operators。给定字符串文字"foo""bar",没有从systm类型获取字符串文字"foo.bar"的编程方法。 GitHub上有一些功能建议,如果实施,可能会使之成为可能,例如key augmentationregular-expression string validation。但是看起来他们并没有积极地工作。