type A = { kind: "kindA", a: "dataA" }
type B = { kind: "kindB", b: "dataB" }
type Sum = A | B
const match = <
const V extends { kind: string },
const C extends { [ kind in V[ "kind" ] ]: ( value: V & { kind: kind } ) => unknown }
>( value: V, cases: C ) => cases[ value.kind as V[ "kind" ] ]( value ) as ReturnType<C[ V[ "kind" ] ]>
// You check the type of result, change the type of value to A or B, make the cases non-exhaustive...
const howToUse = ( value: Sum ) => {
const result = match( value, {
kindA: _ => _.a,
kindB: _ => _.b
} )
}
You can test it here: https://www.typescriptlang.org/play?#code/C4TwDgpgBAglC8UDeU... 2 7 6
9 5 1
4 3 8
Here, if a triplet of one player's cells sums to 15, that player has won.
[0] https://steam250.com/