gpt4 book ai didi

typescript - 用于提取嵌套对象键的类型

转载 作者:搜寻专家 更新时间:2023-10-30 22:00:13 24 4
gpt4 key购买 nike

假设我知道某些数据和嵌套数据结构的类型,如下所示:

interface Element {
foo: string;
bar: string;
}

interface Elements {
[name: string]: Partial<Element>;
}

interface Scopes {
main: Elements;
[other: string]: Elements;
}

然后我有一个函数,它接受一些 Scopes 类型的对象,还有一个参数,它定义了我应该将哪些范围合并到输出对象中(这将在没有范围的情况下被展平)。该函数可能如下所示:

function merge<S extends Scopes>(obj: S, selectors?: { [K in keyof S]?: boolean }): UNKNOWNTYPE {
// this will be some logic to extract and merge scopes
}

我在正确定义此函数 UNKNOWNTYPE 的输出类型时遇到问题。我想动态扁平化并从输入对象中提取 key ,因此对于以下输入数据,我将获得此输出:

const scopes: Scopes = {
main : {
a : {
foo: "a"
},
b : {
bar: "b"
}
},
other : {
b : {
foo : "b"
},
c : {
foo : "c"
}
}
}

const out = merge(scopes, { main : true, other : true });

/*
out is of this strcture

{
a : {
foo : "a"
},
b : {
foo : "b"
bar : "b"
},
c : {
foo : "c"
}
}
*/

我尝试了一些方法并尝试过这种类型,但它没有解析所有合并范围的键:

interface UNKNOWNTYPE<Scopes, Scope extends keyof Scopes = keyof Scopes> {
[K in keyof Scopes[Scope]: Element]
}

有什么方法可以动态展平嵌套对象中的二级对象并将其相交吗?

最佳答案

好吧,我喜欢这种东西。首先:一般来说这样做是不可能的;您需要能够在类型级别枚举键,而 TypeScript 不存在(现在或可能永远不存在)。在你能做到的范围内,你必须握住类型系统的手,因为它不太可能自己推断出你想要它做什么。话虽这么说,但这是一种可能的前进方式:

按照您期望的 scopes 的键数重载函数的次数:

function merge<S extends Scopes, KA extends keyof S>(obj: S, selectors?: {[K in KA]?: boolean}): S[KA];
function merge<S extends Scopes, KA extends keyof S, KB extends keyof S>(obj: S, selectors?: {[K in KA | KB]?: boolean}): S[KA] & S[KB];
function merge<S extends Scopes, KA extends keyof S, KB extends keyof S, KC extends keyof S>(obj: S, selectors?: {[K in KA | KB | KC]?: boolean}): S[KA] & S[KB] & S[KC];
//... merge with 4, 5, 6, etc
function merge<S extends Scopes>(obj: S, selectors?: { [K in keyof S]?: boolean }): Elements {
// this will be some logic to extract and merge scopes
return null as any; // for now
}

然后,当您声明 scopes 时,您可能不应该将类型声明为 Scopes,否则类型系统将忘记您设置的特定键。如果你只是让它推断一个类型,它就会知道所有的键和值类型:

const scopes = {
main : {
a : {
foo: "a"
},
b : {
bar: "b"
}
},
other : {
b : {
foo : "b"
},
c : {
foo : "c"
}
}
}

最后,您可以调用 merge()。您必须明确指定通用类型。第一个是 scopes 变量的类型以及您关心的所有键和值(这只是 typeof scopes 因为我们没有将它设置为 作用域),接下来的是选择器中的各个键:

const out = merge<typeof scopes, 'main','other'>(scopes, { main: true, other: true });
out.a.foo;
out.a.bar; // error as expected
out.b.foo;
out.b.bar;
out.c.foo;
out.c.bar; // error as expected

然后你得到一个你想要的类型的 out。这一切都值得吗?随你(由你决定。祝你好运!

关于typescript - 用于提取嵌套对象键的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45292064/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com