当前位置: 首页 > 面试题库 >

TypeScript:将通用接口作为其他接口的并集

桂志新
2023-03-14
问题内容

我想创建一个具有表示其他接口的属性并集的属性的通用接口。

假设我有两个界面

interface A {
    something: string;
    somethingElse: number;
}

interface B {
    something: Array<string>;
}

我不想将接口写C

interface C {
    something: string | Array<string>;
    somethingElse?: number;
}

因为这意味着每当我修改接口A或时B,我也需要手动修改接口C

根据我在TypeScript文档中看到的内容以及此处关于Stack Overflow的答案,我应该声明一个新类型

type unionOfKeys = keyof A | keyof B;

并实现通用接口形式

interface GenericInterface {
    <T>(arg: T): T;
}

我在朝着

interface C {
    <T extends unionOfKeys>(arg: T): T extends unionOfKeys ? A[T] | B[T] : any
}

但这失败了,因为许多属性与其类型之间不匹配。

我将不胜感激。谢谢。


问题答案:

我认为以下版本的MergeUnion<T>行为可能会符合您的要求:

type MergeUnion<T> = (
  keyof T extends infer K ? [K] extends [keyof T] ? Pick<T, K> & {
    [P in Exclude<(T extends any ? keyof T : never), K>]?:
    T extends Partial<Record<P, infer V>> ? V : never
  } : never : never
) extends infer U ? { [K in keyof U]: U[K] } : never;

type C = MergeUnion<A | B>;
// type C = { 
//  something: string | string[]; 
//  somethingElse?: number | undefined; }
// }

这与其他答案类似,因为它找到T(称为UnionKeys定义T extends any ? keyof T : never)的所有组成部分的所有键的并集,并返回其中包含所有键的映射类型。不同之处在于,在这里我们还找到了T(称为IntersectKeys,定义为keyof T)的所有成分的所有键的交集,并将这些键T分为两组键。交集中的一个存在于每个成分中,因此我们可以做Pick<T, IntesectKeys>以获取公共特性。其余的Exclude<UnionKeys, IntersectKeys>在最终类型中是可选的。

更新2019-08-23:自TS3.5.1起,以下提到的错误似乎已修复

这很丑陋,如果我感觉更好的话,我会清理它。
问题在于,所有成分中出现的任何属性本身都是可选的时,仍然存在问题。TypeScript中存在一个错误(从TS3.5开始),在中 {a?: string} | {a?: number},该 a属性被视为 必需 属性,如 {a: string | number | undefined},而如果任何组成部分将其视为可选,则将其视为可选是更正确的。该错误流到 MergeUnion

type Oops = MergeUnion<{a?: string} | {a?: number}>
// type Oops =  { a: string | number | undefined; }

我在那里没有一个很好的答案,甚至没有更复杂的答案,所以我将在这里停止。

也许这足以满足您的需求。或者,也许@ TitianCernicova-Dragomir的答案足以满足您的需求。希望这些答案对您有所帮助;祝好运!

链接到代码



 类似资料:
  • 本文向大家介绍TypeScript 通用接口,包括了TypeScript 通用接口的使用技巧和注意事项,需要的朋友参考一下 示例 声明通用接口 具有多个类型参数的通用接口 实施通用接口 用泛型类实现它: 用非泛型类实现它:            

  • 总之,是否可以有一个声明某些基属性但不限制其他属性的接口?这是我目前的情况: 我使用的是Flux模式,它定义了一个通用调度器: 然后,我用自己的有效负载类型创建一个调度程序,如下所示: 现在我有了一些动作代码,它应该分派一个带有一些附加数据的有效负载,但是< code>ActionPayload接口只允许< code>actionType。换句话说,这段代码: 给出编译错误,因为与接口不匹配。问题

  • 主要内容:TypeScript,JavaScript,联合类型和接口,TypeScript,JavaScript,接口和数组,实例,实例,TypeScript,接口继承,TypeScript,JavaScript,TypeScript,JavaScript接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法。 TypeScript 接口定义如下: 实例 以下实例中,我们定义了一个接口 IPe

  • Interfaces and other types 接口与其它类型 接口 Interfaces in Go provide a way to specify the behavior of an object: if something can do this, then it can be used here. We’ve seen a couple of simple examples al

  • 除上述接口外Chrome应用还有其他各类丰富的接口,在本章将对其他的接口做以介绍。