【问题标题】:infer generic parameters in rest tuple type推断其余元组类型中的泛型参数
【发布时间】:2020-01-25 08:56:03
【问题描述】:

阅读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&lt;T&gt; 的元组映射到各种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);

【问题讨论】:

    标签: typescript generics tuples inference


    【解决方案1】:

    条件类型没有理由在元组上工作,您的条件类型基本上解决了[typeof Position, typeof Status] extends Attribute&lt;infer T&gt; 的问题,它显然没有解决,所以您最终得到了 never。

    您可以将联合传递给类型 (AttributeTypes&lt;typeof Position | typeof Status&gt;),然后您将得到 Position[] | Status[],这并不是您真正想要的 (Play)

    您也可以在条件类型中使用数组 (Attributes extends Array&lt;Attribute&lt;infer T&gt;&gt; ? 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

    【讨论】:

    • 谢谢,有道理。尽管如此,仍然无法让 AttributeTypes 类型在实践中发挥作用,但对问题进行了更新以描述细节。
    • @DanPrince 您发布的版本作品(与您在操场上的版本不同,参数名称不同)。您只是在返回类型上缺少as any 断言,这是不可避免的。
    • 即使使用as any 断言,使用getAll 时仍然会出现类型错误:Type 'any[]' is missing the following properties from type '[Position, Status]': 0, 1
    • @DanPrince 只是 as any 没有 [] typescriptlang.org/play/#code/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-05
    • 1970-01-01
    • 2020-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多