首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从相交类型构造完整类型

从相交类型构造完整类型
EN

Stack Overflow用户
提问于 2021-12-17 00:36:40
回答 1查看 33关注 0票数 1

我有几种类型是由大量的交叉类型组成的。我想将这些类型提取到它们最终编译到的内容中。我相信当选择重构的方式时,这将是有帮助的。

举个例子。在这种情况下:

代码语言:javascript
复制
type BigType = {
    thing: string
}

type LargeType = {
    blah: boolean
}

type HugeType = BigType & LargeType

我想以某种方式输出:

代码语言:javascript
复制
type HugeType = {
    thing: string
    blah: boolean
}

这是一个小的例子-在现实中有更多的类型交叉在一起。理想情况下,我会输出这些类型的叶子“树”-最大的结果类型。

更多关于原因的信息。我们有一些复制粘贴的代码,类型、视图(反应组件)和业务逻辑(RxJS流)被复制。速度是必需的,所以整个文件夹都被复制粘贴,并且为了一组新的功能需求而调整代码。我们现在要减少这种重复。

我们在RxJS流和React组件树之间有作为类型记录类型编码的视图模型。为了减少重复代码,我们正在讨论的一种方法是将这些视图模型拉到类层次结构中,并在超类中共享公共数据点,改变业务逻辑和视图方面的类型。在这些替换模型就位后,下一步将是重构双方,以减少在相同类型上操作的通用代码。

因此,我想从相交类型构建这些类型(视图模型),因为我认为,当计算出这些不同但非常相似的视图模型之间共享多少时,这将是有益的。对这一方法的反馈欢迎。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-17 02:49:56

如果您正在交叉的类型只有命名成员(因此它们也不充当功能类型构造函数类型),那么您可以通过一个映射类型来获得您要寻找的行为,它迭代一个类型的所有命名成员(甚至是一个交叉点类型),并根据规则为每个成员生成一个属性。如果将映射的类型设置为身份图,其中每个属性都映射到自身:

代码语言:javascript
复制
type Id<T> = { [K in keyof T]: T[K] };

然后,可以将交集类型转换为等效的单对象类型:

代码语言:javascript
复制
type HugeType = Id<BigType & LargeType>;
/* type HugeType = {
    thing: string;
    blah: boolean;
} */

这很好,但有时编译器喜欢在Id快速信息中保留类名,比如IntelliSense。如果您在HugeType上悬停,并且它确实显示了Id<BigType & LargeType>,那么这将比BigType & LargeType更糟糕。

如果遇到这个问题,我所知道的告诉编译器不要保留这些名称的一种方法是使用条件类型推理将一个类型“复制”到一个新的类型参数中,然后使用类型参数代替原始类型:

代码语言:javascript
复制
type HugeType = (BigType & LargeType) extends infer H ?
  { [K in keyof H]: H[K] } : never;

/* type HugeType = {
    thing: string;
    blah: boolean;
} */

它正在执行与以前相同的操作;我们正在BigType & LargeType上执行身份映射,但现在不涉及任何名为Id的类型别名,因此它不能出现在IntelliSense中。

编辑:哦,我看你说的是“树”。如果这意味着对象属性本身具有您可能需要以这种方式合并的属性,那么您可以使用递归定义的身份映射类型(这里的条件类型推断确实有帮助):

代码语言:javascript
复制
type IdRecursive<T> = { [K in keyof T]: IdRecursive<T[K]> } extends
  infer I ? { [K in keyof I]: I[K] } : never

并测试它:

代码语言:javascript
复制
type X = {
  a: {
    b: {
      c: number
    }
  }
}
type Y = {
  a: {
    b: {
      d: string
    }
  }
}

type XY = IdRecursive<X & Y>
/* type XY = {
    a: {
        b: {
            c: number;
            d: string;
        };
    };
} */

操场链接到代码

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70387202

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档