Skip to content

Instantly share code, notes, and snippets.

@captain-yossarian
Created September 6, 2021 08:28
Show Gist options
  • Save captain-yossarian/40cb1570b9716f36409694bbb369ddd2 to your computer and use it in GitHub Desktop.
Save captain-yossarian/40cb1570b9716f36409694bbb369ddd2 to your computer and use it in GitHub Desktop.
SO
type Elem = Param;
type HandleFalsy<T extends Param> = (
T['x'] extends undefined
? T['y']
: (
unknown extends T['x']
? T['y'] : T['x']
)
)
type ArrayMap<
Arr extends ReadonlyArray<Elem>,
Result extends any[] = []
> = Arr extends []
? Result
: Arr extends readonly [infer H, ...infer Tail]
? Tail extends ReadonlyArray<Elem>
? H extends Elem
? ArrayMap<Tail, [...Result, HandleFalsy<H>]>
: never
: never
: never;
type Param<X = unknown, Y = unknown> = {
x?: X
y: Y
}
type Json =
| null
| string
| number
| boolean
| Array<JSON>
| {
[prop: string]: Json
}
const tuple = <
X extends Json,
Y extends Json,
Tuple extends Param<X, Y>,
Arr extends Tuple[]
>(data: [...Arr]) =>
data.map(elem => 'x' in elem ? elem.x : elem.y) as ArrayMap<Arr>
// [42, "only y"]
const result1 = tuple([{ x: 42, y: 'str' }, { y: 'only y' }])
// [42, "only y", "100"]
const result2 = tuple([{ x: 42, y: 'str' }, { y: 'only y' }, { x: '100', y: 999999 }])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment