打字稿类型对象嵌套路径字符串

und*_*ned 2 typescript

我有以下get功能:

function get<T>(obj: T, props: (keyof T)[] | keyof T): any {
  const toArray = coereceArray(props);
  return obj && toArray.reduce(
    (result, prop) => result == null ? undefined : result[prop] as any,
    obj
  );
}

const result = get({ a: { b: 'hey' } }, ['a', 'b']);
const result2 = get({ a: { b: 'hey' } }, 'a'); 
Run Code Online (Sandbox Code Playgroud)

如何根据传递的参数动态输入结果?

Mac*_*ora 6

非常有趣的案例。为了从嵌套对象中收集所有键,我们需要进行递归,幸运的是递归类型在 TS 中可用。但是,如果我们这样做,我们会遇到其他问题,并且确切地说 -Type instantiation is excessively deep and possibly infinite对于这个确切的情况,我们不能说对象可以有多深,请检查此问题以了解我在说什么 -问题

为了执行我们的收集,我们需要设置递归限制。我把限制设置为 5,你可以通过重复模式来扩展它。

首先是类型:

type Level = 0 | 1 | 2 | 3 | 4 | 5 | 'max'; // this solves the infinite loop error issue
type NextLevel<Level> =
    Level extends 0 ? 1
    : Level extends 1 ? 2
    : Level extends 2 ? 3
    : Level extends 3 ? 4
    : Level extends 4 ? 5
    : 'max'; // this type enables iterating from 0 to 5, with the end as 'max'

type NestedKeyof<T, L extends Level = 0> = L extends 'max' ? never : {
    [K in keyof T]: T[K] extends object ? K | NestedKeyof<T[K], NextLevel<L>> : K
}[keyof T]

Run Code Online (Sandbox Code Playgroud)

NestedKeyoftype 是一个映射类型,它收集映射中的所有键,但如果键中的值是一个对象,那么它也会为此对象执行收集。重要的想法是K | NestedKeyof<T[K], NextLevel<L>>,我们递归地传递对象T[K]并通过 迭代级别NextLevel<L>。迭代以maxtype结束,即type 开头可见的内容 - L extends 'max' ? never

该类型的简单测试显示正确的结果:

type NestedType = NestedKeyof<{ a: { b: 'hey', c: { d: 'elo' } } }>; // a | b | c | d
Run Code Online (Sandbox Code Playgroud)

现在如何将它与您的功能一起使用:


function get<T, P extends NestedKeyof<T>>(obj: T, props: P[] | keyof T): any {
  const toArray = coereceArray(props);
  return obj && toArray.reduce(
    (result, prop) => result == null ? undefined : result[prop] as any,
    obj
  );
}

const result = get({ a: { b: 'hey' } }, ['a', 'b']); // correct
const result2 = get({ a: { b: 'hey' } }, 'a');  // correct
const result3 = get({ a: { b: 'hey' } }, ['a', 'b', 'c']); // error as expected
Run Code Online (Sandbox Code Playgroud)

NestedKeyof类型有限制,因为我创建LevelNextLevel为最多5个级别的嵌套的对象。例如这样的类型:

type NestedTypeAboveMax = NestedKeyof
<{ a: { b: 'hey', c: { d: 'elo', e: { f: { g: { h: {i: 'test'}} } } } } }>;
Run Code Online (Sandbox Code Playgroud)

不会拿钥匙,i因为它超出了限制。但是,如果将使用此类嵌套结构,则您可以扩展LevelNextLevel能够拥有更多级别。