[英]Typescript: infer generic types in generic type constraint
I have a generic interface that takes a type argument that must extend another generic type.我有一个通用接口,它接受一个必须扩展另一个通用类型的类型参数。 For example:例如:
export interface IPoint<TX, TY>
{
x: TX;
y: TY;
}
export interface ISeries<TPoint extends IPoint>
{
points: Array<TPoint>;
}
Here, I must specify TX
and TY
for IPoint
.在这里,我必须为IPoint
指定TX
和TY
。
My question is: is there a way to infer those types automatically, for example like this?我的问题是:有没有办法自动推断这些类型,例如像这样?
export interface ISeries<TPoint extends IPoint<infer TX, infer TY>>
{
points: Array<TPoint>;
}
The only way to make this work I've found for now is to add TX
and TY
as type parameters for ISeries
, but it's quite impractical because then I have to specify the three types every time I use the interface.我目前发现的使这项工作起作用的唯一方法是将TX
和TY
添加为ISeries
的类型参数,但这是非常不切实际的,因为每次使用该接口时我都必须指定这三种类型。
I could also use IPoint<any, any>
, but then I lose the information about the real types of x
and y
.我也可以使用IPoint<any, any>
,但是我丢失了有关x
和y
的真实类型的信息。
EDIT: To add some clarification about what I want to achieve, let's consider the following example:编辑:为了澄清我想要实现的目标,让我们考虑以下示例:
export interface ISeries<TPoint extends IPoint<infer TX, infer TY>>
{
points: Array<TPoint>;
transformYValues?: (yValue: TY) => number;
}
Here I would need TY
to strongly type transformYValues
.在这里我需要TY
来强类型transformYValues
。
Thanks for your help谢谢你的帮助
EDIT 2: Found a solution (thanks captain-yossarianfromUkraine).编辑 2:找到解决方案(感谢来自乌克兰的 captain-yossarian)。
export interface ISeries<TPoint extends IPoint<any, any>>
{
points: Array<TPoint>;
transformYValues?: (yValue: TPoint['y']) => number;
}
The key here is TPoint['y']
, I wasn't aware of this neat feature called Indexed Access Types (see https://www.typescriptlang.org/docs/handbook/2/indexed-access-types.html ).这里的关键是TPoint['y']
,我不知道这个称为索引访问类型的简洁功能(请参阅https://www.typescriptlang.org/docs/handbook/2/indexed-access-types.html ) .
In summary => use any
typing in the generic type constraints, then use indexed access types to strongly type methods/properties inside the interface.总之 => 在泛型类型约束中使用any
类型,然后使用索引访问类型在接口内强类型化方法/属性。
Consider this example:考虑这个例子:
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
}
})
I added Values
type as a constraint for allowed x
and y
data types.我添加了Values
类型作为允许的x
和y
数据类型的约束。
Also, I have added a function inference
because type inference works with generic conditional types and function arguments.此外,我添加了一个 function inference
,因为类型推理适用于通用条件类型和 function arguments。
To infer literal type x:1 y:2
I have used variadic tuple types , see this [...Points]
要推断文字类型x:1 y:2
我使用了可变元组类型,请参阅此[...Points]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.