typescript - { foo: null } 与 type { bar?: null; 没有共同的属性 fnord?: 空 }
问题描述
我有一些类型,它们共享共同的道具,但这些道具有不同的对象。我想合并这些子对象,但它没有按我的预期工作。这是我的代码:
interface IFoo { foo: any };
interface IBarFnord { bar?: any; fnord?: any };
type Union = {test: IFoo } & {test: IBarFnord; otherTest?: IBarFnord };
const fails: Union = { test: { foo: null }};
const works: Union = { test: {foo: null, bar: null }};
const alsoWorks: Union = { test: {foo: null, fnord: null }};
因为const fails
我得到了错误:
类型 '{ foo: null; }' 与类型 'IBarFnord' 没有共同的属性。
这是真的。如果联合手段必须在两者中都有属性,那么它是有道理的。
我已经测试过这样做不是作为子道具,它工作正常:
type Union = {test: IFoo & IBarFnord };
const worksNow: Union = { test: { foo: null }};
const stillWorks: Union = { test: {foo: null, bar: null }};
无论如何,我怎么能告诉 Typescript 我想联合这些东西,但我不希望每个项目总是在联合的两边都有道具?
解决方案
假设您实际上是指“交叉口”而不是“联合”,这看起来像是一个已知问题,其中过多的属性检查分别适用于交叉口的每个组成部分,而实际上它应该只适用于整个交叉口。看起来最近已经做了一些工作来解决这个问题,所以也许修复会使其成为即将发布的版本?没有把握。
无论如何,作为一种解决方法,我们可以创建自己的类型别名,它可以积极地递归地合并交集类型中的子属性,如下所示:
type SubpropertyMerge<T> = T extends (...args: infer A) => infer R
? (...args: SubpropertyMerge<A>) => SubpropertyMerge<R>
: T extends object ? { [K in keyof T]: SubpropertyMerge<T[K]> } : T;
此类型应将由基元、对象、数组/元组和非泛型函数组成的类型转换为合并任何交集的等效类型:
type Test = {
a: string;
b: number[];
c: {
d: boolean;
e: string | { f: number };
};
g: [string, number, { h: number }];
h: () => string;
i: (x: number) => number;
j: (x: { foo: string }) => number[];
};
type MergedTest = SubpropertyMerge<Test>; // looks the same
// MutuallyExtends<A, B> is a compile error unless A and B are mutually assignable
type MutuallyExtends<T extends U, U extends V, V=T> = true;
type TestIsOkay = MutuallyExtends<Test, MergedTest>; // acts the same
它应该适用于您的类型,我已将其重命名为Intersection
:
type MergedIntersection = SubpropertyMerge<Intersection>;
type IntersectionIsOkay = MutuallyExtends<Intersection, MergedIntersection>; // acts the same
但是现在你的作业应该如你所愿:
const worksNow: MergedIntersection = { test: { foo: null } };
好的,希望有帮助;祝你好运!
推荐阅读
- r - 合并两个数据框会比 R 中的原始数据创建更多的行
- react-native - 如何使用 AWS AppSync / DynamoDB(React Native)创建具有联合作为字段的 Mutation
- c# - VDS.RDF.Parsing.RdfXmlParser 加载(IRdfHandler 处理程序,XmlDocument 文档)丢失
- c++ - C++ 类中使用引用的循环依赖
- php - PHPmail 附件无法到达 Gmail + 格式错误
- r - 重复测量的逻辑回归模型是什么?
- angular - 如何在选择触发事件上测试组件
- python - 使用python循环从一个数据框在一个excel工作簿中创建多个excel表
- mysql - 如何以ms访问形式将mysql中数据库中的数据或表显示为可编辑?(像列表框一样可编辑)
- flutter - 从图库/相机中取消图像选择器时出现 Image.path 错误