Skip to content

Instantly share code, notes, and snippets.

@Phryxia
Last active December 6, 2022 17:39
Show Gist options
  • Save Phryxia/5a62a579b6367d0ed52d98696b4c27f7 to your computer and use it in GitHub Desktop.
Save Phryxia/5a62a579b6367d0ed52d98696b4c27f7 to your computer and use it in GitHub Desktop.
TypeScript implementation of cartessian product which infers its type perfectly.
type CartessianType<T> =
T extends [] ?
[] :
T extends [(infer R)[], ...infer Rest] ?
[R, ...CartessianType<Rest>] :
T extends (infer R)[][] ?
[R] :
never
function cartessianProduct<T extends unknown[]>(...sets: T): CartessianType<T>[]
function cartessianProduct(s: any[], ...rest: any[]): any[][] {
if (rest.length === 0) return s.map((e: any) => [e])
const pre = cartessianProduct(s)
const post = cartessianProduct(rest[0], ...rest.slice(1))
const result: any[] = []
for (const p of pre) {
for (const q of post) {
result.push([p[0], ...q as any[]])
}
}
return result
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment