I wrote a simple Cartesian product implementation in Typescript, but the type inferred is not what I have expected:
export function cartesianProduct<X, Y> (a: X[], b: Y[]): Array<[X, Y]> {
return a.flatMap(x => b.map(y => [x, y]));
}
As you can see, the inferred type is (X | Y)[][] instead of [X, Y][]
. This seems weird to me because [x, y]
should have type [X, Y]
(x is of X type and y is of Y type).
Any idea why I am getting this type error and how to fix?
2
Answers
Typescript is confused about your types. Your code makes it seem like you want an array which returns more arrays which have a mix of your X and Y. However, it seems you want an array of pairs which would be [X, Y].
To fix your error, you would have to define that the inner arrays should be [X, Y].
Like this:
}
TypeScript generally infers array literals like
[x, y]
to have array types instead of tuple types. If you want to change this, you need to give the type checker context for which it to infer the type differently. There are various ways to go about this (such as aconst
assertion, or using a type assertion with theas
operator, or by manually specifying the generic type argument tomap
asmap<[X, Y]>
).Currently the approach I’d most recommend is to use the
satisfies
operator; if you writeexpr satisfies Type
it will tell the compiler to useType
as context for inferringexpr
‘s type. If it can infer a compatible type it will; otherwise it will produce an error, so thesatisfies
operator is type safe in a way that a type assertion is not.So all you need to do is this:
And it works.
Playground link to code