是否可以使用通用休息类型创建类型?

时间:2019-02-24 18:27:37

标签: typescript

出现在类型Defining a choice of index type on an interface之间进行选择的问题

我现在必须创建一个元素序列,通常可以将其写为element1 & element2,但是由于我要转换XSD架构,因此我希望它是一对一的匹配,以便使用新的TypeScript开发人员不会对正在发生的事情感到困惑。

目前我有这种类型

type Object_Type<T> = { [P in keyof T]: T[P] };
type Sequence<A, B = {}, C = {}, D = {}, E = {}, F = {}, G = {}, H = {}, I = {}, J = {}, K = {}, L = {}, M = {}, N = {}> =
    Object_Type<A>
    & Object_Type<B>
    & Object_Type<C>
    & Object_Type<D>
    & Object_Type<E>
    & Object_Type<F>
    & Object_Type<G>
    & Object_Type<H>
    & Object_Type<I>
    & Object_Type<J>
    & Object_Type<K>
    & Object_Type<L>
    & Object_Type<M>
    & Object_Type<N>;

并且可以像这样使用

const sequence: Sequence<{name: string}, {age: number}> = {
    name: "John",
    age: 999
};

但是,手动定义每个通用参数并给它们提供默认值非常极端,所以我想知道是否可以像这样定义

type Sequence<...T> = Object_Type<...T>;

1 个答案:

答案 0 :(得分:2)

TypeScript中没有显式的variadic kinds,因此Sequence<...T>之类的精确表述不起作用。但是您可以像在Sequence<[{name: string}, {age: number}]>中那样使用tuple type。给定一个元组类型,您可以map itObject_Type,通过looking upnumber属性,然后convert the union to an intersection将元组转换为联合。

type Object_Type<T> = { [P in keyof T]: T[P] };
type UnionToIntersection<U> =
  (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
type Sequence<T extends any[]> = 
  UnionToIntersection<{ [K in keyof T]: Object_Type<T[K]> }[number]>;

const sequence: Sequence<[{ name: string }, { age: number }]> = {
  name: "John",
  age: 999
};

这是可行的,尽管可能存在一些不同的极端情况(例如,如果您的个人AB等类型本身是并集)。这些可能会被解决,但是...我想我不明白这里的用例。 Object_Type通常是无人值守,那么您在做什么呢?通过表达式Sequence<A,B,C>(或者在我的版本中为Sequence<[A,B,C]>),您从A & B & C中得不到什么?也许您能详细说明一下,对于您尝试做的事情会有一个更简单或更好的解决方案。