提取TypeScript中可选属性的嵌套字段的路径

j9per5c4  于 2023-02-05  发布在  TypeScript
关注(0)|答案(1)|浏览(168)

我有一个用例,需要提取TypeScript interface中嵌套字段的所有可能路径。
当我在具有嵌套和可选属性的“main”类型中定义一个属性时,它会按预期工作。但是,我遇到了一个指向另一个接口的可选属性的问题。

type NestedKeyOf<T extends object> = {
  [Key in keyof T & (string | number)]: T[Key] extends object
    ? `${Key}` | `${Key}.${NestedKeyOf<T[Key]>}`
    : `${Key}`;
}[keyof T & (string | number)];

interface MyParameters {
  Foo: string;
  Bar?: string;
}

interface MyObject {
  Parameters?: MyParameters;
  Foo: {
    Bar?: string;
  }
}

// Here, I'd expect "Parameters.Foo" and "Parameters.Bar" to also exist
// Instead, all I get is "Parameters" | "Foo" | "Foo.Bar"

type Path = NestedKeyOf<MyObject> // "Parameters" | "Foo" | "Foo.Bar"
  • TypeScriptPlayground

有没有人能解释一下这种行为的原因?谢谢!

scyqe7ek

scyqe7ek1#

问题是如果Parameters是可选的,type Test = MyObject["Parameters"] extends object ? true : false的计算结果为false。您可以通过排除使用Exclude<T[Key], undefined> extends object而不是T[Key] extends object(playground)未定义它的情况来解决此问题:

type NestedKeyOf<T extends object> = {
  [Key in keyof T & (string | number)]: Exclude<T[Key], undefined> extends object
    ? `${Key}` | `${Key}.${NestedKeyOf<Exclude<T[Key], undefined>>}`
    : `${Key}`;
}[keyof T & (string | number)];

interface MyParameters {
  Foo: string;
  Bar?: string;
}

interface MyObject {
  Parameters?: MyParameters;
  Foo: {
    Bar?: string;
  }
}

type Path = NestedKeyOf<MyObject>

相关问题