我有以下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)
如何根据传递的参数动态输入结果?
非常有趣的案例。为了从嵌套对象中收集所有键,我们需要进行递归,幸运的是递归类型在 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类型有限制,因为我创建Level和NextLevel为最多5个级别的嵌套的对象。例如这样的类型:
type NestedTypeAboveMax = NestedKeyof
<{ a: { b: 'hey', c: { d: 'elo', e: { f: { g: { h: {i: 'test'}} } } } } }>;
Run Code Online (Sandbox Code Playgroud)
不会拿钥匙,i因为它超出了限制。但是,如果将使用此类嵌套结构,则您可以扩展Level并NextLevel能够拥有更多级别。
| 归档时间: |
|
| 查看次数: |
938 次 |
| 最近记录: |