推断剩余元组类型的通用参数

时间:2019-09-25 07:55:54

标签: typescript generics tuples inference

了解rest elements in tuple types并尝试弄清楚如何提取类型的通用部分:

type Attribute<Type> = { id: string, type?: Type };

type Position = { x: number, y: number };
let Position: Attribute<Position> = { id: "position" };

type Status = "active" | "inactive";
let Status: Attribute<Status> = { id: "status" };

我确定有一种方法可以编写条件类型,该条件类型会将各种Attribute<T>的元组映射到各种T的元组。

type AttributeTypes<Attributes extends Attribute<any>[]> =
   Attributes extends Attribute<infer T> ? T[] : never;

type Result = AttributeTypes<[typeof Position, typeof Status]> // should be `[Position, Status]`

但是我对推理步骤的理解不够充分,它总是以never分支结束。

最后一步将是编写一个将推断类型用作返回(Playground)一部分的函数:

function getAll<Attributes extends Attribute<any>[]>(
  ...attributes: Attributes
): AttributeTypes<Attributes> {
  return attributes.map(attribute => attribute.type);
}

let [position, status]: [Position, Status] = getAll(Position, Status);

1 个答案:

答案 0 :(得分:2)

条件类型没有理由在元组上工作,您的条件类型基本上可以解决问题[typeof Position, typeof Status] extends Attribute<infer T>,而问题AttributeTypes<typeof Position | typeof Status>显然没有,因此您永远都不会。

您可以将联合输入类型(Position[] | Status[])中,然后将得到Attributes extends Array<Attribute<infer T>> ? T[] : never,它并不是您想要的(Play

您还可以在条件类型(type Attribute<Type> = { id: string, type?: Type }; type Position = { x: number, y: number }; let Position: Attribute<Position> = { id: "position" }; type Status = "active" | "inactive"; let Status: Attribute<Status> = { id: "status" }; type AttributeTypes<Attributes extends Attribute<any>[]> = { [P in keyof Attributes]: Attributes[P] extends Attribute<infer T> ? T : never; } type Result = AttributeTypes<[typeof Position, typeof Status]> // is [Position, Status] )中使用数组,但不会在输入(Play)中保留元组结构

获得所需输出的最佳方法是使用映射类型。映射类型保留元组,同时允许您将元组的每种元素类型映射到结果元组中的新元素类型:

<span id="color" class="section-id">Colore</span>
<div class="wrap-holder">
<div class="box" id="DivOLTRECover" runat="server"><asp:RadioButton ID="CoverOltre" 
GroupName="CoverOltre" runat="server"   Checked="true" /><span runat="server"><span class="img" > 
<img src="Oltre/Img/Cover.png" alt=""/></span>Cover</span><div class="image-box"><img 
src="Oltre/Img/Cover.png" alt=""/></div></div>      



<div class="box" id="Div_OLTRE_AirSlightGrain6009" runat="server"><asp:RadioButton 
ID="OLTRE_AirSlightGrain6009" GroupName="Superficie" runat="server" value="AIR SLIGHTGRAIN 6009"  /> 
<span runat="server"><span class="img" ><img 
src="Oltre/Superfici/AIR_SLIGHTGRAIN/AIR_SLIGHTGRAIN_6009.png" alt=""/></span>6009</span><div 
class="image-box"><img src="Oltre/Superfici/AIR_SLIGHTGRAIN/AIR_SLIGHTGRAIN_6009.png" alt=""/></div> 
</div>  



<div class="box" id="Div_OLTRE_AirSlightGrain7016" runat="server"><asp:RadioButton 
ID="OLTRE_AirSlightGrain7016" GroupName="Superficie" runat="server"  /><span runat="server"><span 
class="img" ><img src="Oltre/Superfici/AIR_SLIGHTGRAIN/AIR_SLIGHTGRAIN_7016.png" alt=""/> 
</span>7016</span><div class="image-box"><img 
src="Oltre/Superfici/AIR_SLIGHTGRAIN/AIR_SLIGHTGRAIN_7016.png" alt=""/></div></div> 



<div class="box" id="Div_OLTRE_AirSlightGrain7035" runat="server"><asp:RadioButton 
ID="OLTRE_AirSlightGrain7035" GroupName="Superficie" runat="server"  /><span runat="server"><span 
class="img" ><img src="Oltre/Superfici/AIR_SLIGHTGRAIN/AIR_SLIGHTGRAIN_7035.png" alt=""> 

Play