繁体   English   中英

Typescript:在通用类型约束中推断通用类型

[英]Typescript: infer generic types in generic type constraint

我有一个通用接口,它接受一个必须扩展另一个通用类型的类型参数。 例如:

export interface IPoint<TX, TY>
{
    x: TX;
    y: TY;
}
export interface ISeries<TPoint extends IPoint>
{
    points: Array<TPoint>;
}

在这里,我必须为IPoint指定TXTY

我的问题是:有没有办法自动推断这些类型,例如像这样?

export interface ISeries<TPoint extends IPoint<infer TX, infer TY>>
{
    points: Array<TPoint>;
}

我目前发现的使这项工作起作用的唯一方法是将TXTY添加为ISeries的类型参数,但这是非常不切实际的,因为每次使用该接口时我都必须指定这三种类型。

我也可以使用IPoint<any, any> ,但是我丢失了有关xy的真实类型的信息。

编辑:为了澄清我想要实现的目标,让我们考虑以下示例:

export interface ISeries<TPoint extends IPoint<infer TX, infer TY>>
{
    points: Array<TPoint>;
    transformYValues?: (yValue: TY) => number;
}

在这里我需要TY来强类型transformYValues

谢谢你的帮助

编辑 2:找到解决方案(感谢来自乌克兰的 captain-yossarian)。

export interface ISeries<TPoint extends IPoint<any, any>>
{
    points: Array<TPoint>;
    transformYValues?: (yValue: TPoint['y']) => number;
}

这里的关键是TPoint['y'] ,我不知道这个称为索引访问类型的简洁功能(请参阅https://www.typescriptlang.org/docs/handbook/2/indexed-access-types.html ) .

总之 => 在泛型类型约束中使用any类型,然后使用索引访问类型在接口内强类型化方法/属性。

考虑这个例子:

export interface Point<X, Y> {
  x: X;
  y: Y;
}

type Values = string | number

export interface Series<Points extends Point<Values, Values>[]> {
  points: Points;
  transformYValues: (yValue: Points[number]['y']) => number;
}

const inference = <
  X extends Values,
  Y extends Values,
  Points extends Point<X, Y>[]
>(data: Series<[...Points]>) => void 0


inference({
  points: [{ x: 1, y: 2 }, { x: 1, y: 9 }],
  transformYValues: (arg) => {
    arg // 2 | 9
    return 42
  }
})

操场

我添加了Values类型作为允许的xy数据类型的约束。

此外,我添加了一个 function inference ,因为类型推理适用于通用条件类型和 function arguments。

要推断文字类型x:1 y:2我使用了可变元组类型,请参阅此[...Points]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM