typescript - TypeScript 中对象值类型的交集
问题描述
我有一个 TypeScript interface
,它定义了我可以在 REST 端点上使用的 HTTP 方法和查询参数类型(请参阅人行横道,了解您为什么要这样做的详细信息):
interface API {
'/endpoint': {
get: {a?: string, b?: string};
post: {b?: string, c?: string};
}
}
我想定义一个函数,它采用这种 API 类型、端点 ( '/endpoint'
) 以及可选的 HTTP 动词 ( 'get'
,'post'
等) 和适当的查询参数:
const urlMaker = apiUrlMaker<API>();
urlMaker('/endpoint')({a: 'a', b: 'b'}); // should be an error, we don't know that "a" is OK.
urlMaker('/endpoint')({b: 'b'}); // fine, "b" is always safe. Should return "/endpoint?b=b".
urlMaker('/endpoint', 'get')({a: 'a', b: 'b'});
// fine, we're explicitly using get. Should return "/endpoint?a=a&b=b".
在用户省略 HTTP 动词的情况下,我想接受此方法的查询参数类型的交集(即可以传递给任何动词的查询参数类型)。
我可以通过这种方式获得类型的联合:
type ParamUnion = API['/endpoint'][keyof API['/endpoint']];
// type is {a?: string, b?: string} | {b?: string, c?: string}
我知道将 unions 转换为 intersections的技巧,但我想知道在这种情况下是否有一种方法可以不通过联合体。当然,除了get
和post
( delete
, put
,patch
等) 之外,还可以为端点定义任意数量的 HTTP 动词。
解决方案
我会使用相同的基本技术,因为据我所知,条件类型推断 withinfer
是 TS 中唯一会自动生成任意数量类型的交集的功能(无需求助于递归)。您不必先明确地通过联合,尽管它仍然隐含在其中:
type ParamIntersection = {
[K in keyof API['/endpoint']]: (x: API['/endpoint'][K]) => void
}[keyof API['/endpoint']] extends
(x: infer I) => void ? I : never;
/* type ParamIntersection = {
a?: string | undefined;
b?: string | undefined;
} & {
b?: string | undefined;
c?: string | undefined;
} */
我将每个属性类型转换为函数的参数,然后获取这些函数的并集,并从中推断出单个参数,这通过函数参数逆变的魔力将并集变成了交集。
这种类型有点难看,如果有更多的交集构成会变得更糟,所以你也可以将它们合并成一个对象类型:
type ParamMerged = {
[K in keyof API['/endpoint']]: (x: API['/endpoint'][K]) => void
}[keyof API['/endpoint']] extends
(x: infer I) => void ? { [K in keyof I]: I[K] } : never;
/* type ParamIntersection = {
a?: string | undefined;
b?: string | undefined;
c?: string | undefined;
} */
推荐阅读
- python-3.x - 在我的本地机器上运行时出现 Flask 404 错误
- rest - 通过 REST 将 Azure DevOps 服务器管道的构建状态发送到 Bitbucket
- intellij-idea - java: 你没有使用 lombok 支持的编译器,所以 lombok 将无法工作并且已被禁用
- amazon-web-services - 如何在 AWS 中的安全组内和跨安全组自动使用公共 IP 地址替换分配的入站规则?
- javascript - Bootstrap 选择可编辑组合框黑客
- java - 如何在浏览器中打开pdf文件
- python-3.x - Python等待/暂停直到特定时间......并在计划结束时停止
- python - 如何从函数内的循环中获取向量/数组输出?
- jboss - Wildfly 服务器多个域?
- python - 如何在 tkinter 中删除多边形?