[英]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
指定TX
和TY
。
我的问题是:有没有办法自动推断这些类型,例如像这样?
export interface ISeries<TPoint extends IPoint<infer TX, infer TY>>
{
points: Array<TPoint>;
}
我目前发现的使这项工作起作用的唯一方法是将TX
和TY
添加为ISeries
的类型参数,但这是非常不切实际的,因为每次使用该接口时我都必须指定这三种类型。
我也可以使用IPoint<any, any>
,但是我丢失了有关x
和y
的真实类型的信息。
编辑:为了澄清我想要实现的目标,让我们考虑以下示例:
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
类型作为允许的x
和y
数据类型的约束。
此外,我添加了一个 function inference
,因为类型推理适用于通用条件类型和 function arguments。
要推断文字类型x:1 y:2
我使用了可变元组类型,请参阅此[...Points]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.