Typescript 推断rest元组类型中的泛型参数

Typescript 推断rest元组类型中的泛型参数,typescript,generics,tuples,inference,Typescript,Generics,Tuples,Inference,阅读并试图找出如何提取类型的泛型部分: 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<Stat

阅读并试图找出如何提取类型的泛型部分:

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" };
但是我对推理步骤理解得不够透彻,它总是以
never
分支结束

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

函数getAll( …属性:属性 ):AttributeType{ 返回attributes.map(attribute=>attribute.type); } let[position,status]:[position,status]=getAll(position,status);
条件类型没有理由处理元组,您的条件类型基本上解决了问题
[typeof Position,typeof Status]扩展属性
,但它显然没有这样做,因此您最终得到的是never

您可以将一个联合传递到类型(
attributeType
)中,然后您将获得
位置[]|状态[]
,这并不是您真正想要的()

您还可以在条件类型中使用数组(
Attributes扩展数组)

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

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]
type属性={id:string,type?:type};
类型位置={x:number,y:number};
let Position:Attribute={id:“Position”};
键入Status=“active”|“inactive”;
let Status:Attribute={id:“Status”};

类型attributeType

条件类型没有理由处理元组,您的条件类型基本上解决了问题
[typeof Position,typeof Status]扩展属性
,但它显然没有这样做,因此您最终得到的是never

您可以将一个联合传递到类型(
attributeType
)中,然后您将获得
位置[]|状态[]
,这并不是您真正想要的()

您还可以在条件类型中使用数组(
Attributes扩展数组)

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

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]
type属性={id:string,type?:type};
类型位置={x:number,y:number};
let Position:Attribute={id:“Position”};
键入Status=“active”|“inactive”;
let Status:Attribute={id:“Status”};

键入AttributeType

谢谢,这很有意义。不过,仍然无法让
attributeType
类型在实践中起作用,对问题进行了更新,以描述细节。@DanPrince您发布的版本有效(它与您在操场上的版本不同,参数名称不同)。在返回类型上,您只缺少一个
as any
断言,这是不可避免的。即使使用
as any
断言,在使用
getAll
时,我仍然会遇到一个类型错误:
type'any[]缺少类型“[Position,Status]”的以下属性:0,1
@DanPrince just
as any
no
[]
谢谢,这很有道理。不过,仍然无法让
attributeType
类型在实践中起作用,对问题进行了更新,以描述细节。@DanPrince您发布的版本有效(它与您在操场上的版本不同,参数名称不同)。在返回类型上,您只缺少一个
as any
断言,这是不可避免的。即使使用
as any
断言,在使用
getAll
时,我仍然会遇到一个类型错误:
type'any[]'缺少类型“[Position,Status]”的以下属性:0,1
@DanPrince just
as any
no
[]
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]