typescript - 将数组转换为具有来自数组元素中的公共属性的键的对象
问题描述
我有一个类似的对象:
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>;
}
密码沙盒: https ://codesandbox.io/s/56564
解决方案
你很接近,但问题是你T
是一个具体类型而不是泛型类型参数,因此T extends { pointer: K } ? T : never
不会分配 unions。所以T extends { pointer: K }
对于 , 的每个选择都是错误的K
,你得到never[]
的不是你想要的。
获取分布式条件类型的最简单方法是使用表单的类型别名,type Something<X> = X extends { pointer: K } ? X : never
然后插入Something<T>
. 幸运的是,内置Extract<T, U>
实用程序类型已经以这种方式工作。所以我们可以这样写:
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
好的,希望有帮助;祝你好运!
推荐阅读
- php - 如何在 graphql-laravel 中使用 UnionType?
- javascript - 如何使用 Web Speech API 以一种可以听到 textarea 行的单词的方式,每行都以延迟的方式?
- c# - 为什么我的 ASP.NET Web 表单呈现缓慢?
- javascript - 人脸对比API
- javascript - 如何使分页位于选项卡内的页面底部?
- python - Discord.py - 使用计时器静音消息
- amazon-web-services - 如何根据某些属性将放大模型数据写入多个表并轻松查询?
- flutter - NullPointerException flutter_local_notifications 在版本更新后不起作用
- python - Google Nearby Places API 调用 - 请求无效
- jira - 在 Jira Software 中看不到“路线图”功能