使用数组元素中公共 属性 的键将数组转换为对象
Transforming an array to an object with key from common property in elements of array
我有一个类似这样的对象:
const v = [
{ pointer: "/name", name: "N1" },
{ pointer: "/name", name: "N2" },
{ pointer: "/zip", name: "Z1" }
] as const
我想生成这样的对象:
const m: M = {
"/name": [{ pointer: "/name", name: "N2" }] // can also contain N1, but not Z1
}
是否可以为此创建一个类型?我的尝试应该更好地解释我正在尝试做的事情:
type V = typeof v;
type T = V[number]
type M = {
[K in T["pointer"]]: Array<T extends {pointer: K} ? T : never>;
}
codesandbox: https://codesandbox.io/s/56564
你很接近,但问题是你的 T
是具体类型而不是泛型类型参数,因此 T extends { pointer: K } ? T : never
不是 distributive over unions。所以 T extends { pointer: K }
对于 K
的每个选择都是假的,你得到 never[]
而不是你要找的东西。
恢复分布式条件类型的最简单方法是使用 type Something<X> = X extends { pointer: K } ? X : never
形式的类型别名,然后插入 Something<T>
。幸运的是,内置的 Extract<T, U>
utility type 已经可以这样工作了。所以我们可以这样写:
type M = { [K in T["pointer"]]?: Array<Extract<T, { pointer: K }>> };
计算结果为:
/*
type M = {
"/name"?: ({
readonly pointer: "/name";
readonly name: "N1";
} | {
readonly pointer: "/name";
readonly name: "N2";
})[];
"/zip"?: {
readonly pointer: "/zip";
readonly name: "Z1";
}[];
}
*/
我认为哪个更接近您想要的。请注意,我将道具设为可选,因为您的 m
常量没有所有道具:
const m: M = {
"/name": [{ pointer: "/name", name: "N2" }]
}; // okay
好的,希望对您有所帮助;祝你好运!
我有一个类似这样的对象:
const v = [
{ pointer: "/name", name: "N1" },
{ pointer: "/name", name: "N2" },
{ pointer: "/zip", name: "Z1" }
] as const
我想生成这样的对象:
const m: M = {
"/name": [{ pointer: "/name", name: "N2" }] // can also contain N1, but not Z1
}
是否可以为此创建一个类型?我的尝试应该更好地解释我正在尝试做的事情:
type V = typeof v;
type T = V[number]
type M = {
[K in T["pointer"]]: Array<T extends {pointer: K} ? T : never>;
}
codesandbox: https://codesandbox.io/s/56564
你很接近,但问题是你的 T
是具体类型而不是泛型类型参数,因此 T extends { pointer: K } ? T : never
不是 distributive over unions。所以 T extends { pointer: K }
对于 K
的每个选择都是假的,你得到 never[]
而不是你要找的东西。
恢复分布式条件类型的最简单方法是使用 type Something<X> = X extends { pointer: K } ? X : never
形式的类型别名,然后插入 Something<T>
。幸运的是,内置的 Extract<T, U>
utility type 已经可以这样工作了。所以我们可以这样写:
type M = { [K in T["pointer"]]?: Array<Extract<T, { pointer: K }>> };
计算结果为:
/*
type M = {
"/name"?: ({
readonly pointer: "/name";
readonly name: "N1";
} | {
readonly pointer: "/name";
readonly name: "N2";
})[];
"/zip"?: {
readonly pointer: "/zip";
readonly name: "Z1";
}[];
}
*/
我认为哪个更接近您想要的。请注意,我将道具设为可选,因为您的 m
常量没有所有道具:
const m: M = {
"/name": [{ pointer: "/name", name: "N2" }]
}; // okay
好的,希望对您有所帮助;祝你好运!