#Anyone with experience in ts-pattern has matched on first element of a known tuple?

1 messages · Page 1 of 1 (latest)

normal krakenBOT
#
itstheandre#0

Preview:```ts
import {match, P} from "ts-pattern"
type A = "foo" | "bar"

type Args<T extends A> = T extends "foo"
? {hello: "world"}
: {baz: "quz"}

type Tuple<T extends A> = [key: T, args: Args<T>]

function makeTest<T extends A>(...options: Tuple<T>) {
match(options).with(["foo", P.any], ()
...```

real grove
#

i got an error in the first option of the tuple

drifting sapphire
#

but even the exact example they provide doesn't seem to typecheck (though it has different errors than your example)

real grove
#

yeah, i thought so hence my confusion :/

drifting sapphire
#

on the other hand, this does work:

normal krakenBOT
#
mkantor#0

Preview:```ts
import {match, P} from "ts-pattern"

type Test =
| ["foo", {hello: "world"}]
| ["bar", {baz: "quz"}]

declare const test: Test
match(test).with(["foo", P.any], () => {})```

drifting sapphire
#

i guess the fact that it's generic in your original version is problematic

real grove
#

oh, ok

#

hmmm, curious how to build this generic from scratch then, i thought i had a straightforward logic

drifting sapphire
#

why do you need it to be generic?

real grove
#

which part, specifically?

drifting sapphire
#

whatever part you were referring to with "build this generic from scratch" 😄

real grove
#

ah, sorry

drifting sapphire
#

like i am guessing the non-generic discriminated union approach i shared doesn't fit your real use case, i'm wondering why

real grove
#

tbh, it seemed like it would be easier to build with generic, perhaps

#

clearly i was wrong

#

is actually better the way you put, less types and less magic

drifting sapphire
#

yeah i usually default to non-generic unions like this unless i have a reason not to (like if i can't know all the possible variants upfront)

real grove
#

i think its because i wanted to enforce that it needed to enforced by the keyof another type

#

thats why i had the union as an example of 'keyof' another type

#

as per usual, almost every time i ask a question, you come and save the day, thanks @drifting sapphire

normal krakenBOT
#

@real grove Here's a shortened URL of your playground link! You can remove the full link from your message.

itstheandre#0

Preview:```ts
import {match, P} from "ts-pattern"

type Test =
| ["foo", {hello: "world"}]
| ["bar", {baz: "quz"}]

function test(...arg: Test) {}
test("foo", {baz: "quz"})```

real grove
#

is this expected?

#

@drifting sapphire

drifting sapphire
#

autocomplete has many quirks like this. i'm not sure "expected" is the right term, but it's "normal" for functions with overloads to have that behavior

#

(and what you have there is equivalent to an overload)

#

consider this example too:

normal krakenBOT
#
mkantor#0

Preview:ts function test(a: number, b: "number"): void function test(a: string, b: "string"): void function test(a: any, b: any) {} test(1, "") // type s between the ''

real grove
#

hmm, so even though the type checker can figure out something is wrong we fing ourselves the issue of the matter of typescript server autocomplete feature not being in line with the type checker?

drifting sapphire
#

i don't know if this is the rationale, but it could be intentional because your first argument might be the one that's "wrong"

real grove
#

fair enough

drifting sapphire
#

i'm thinking about this case too, where you've entered the second parameter and go back to add/edit the first one:

normal krakenBOT
#
mkantor#0

Preview:ts function test(a: "number", b: "number"): void function test(a: "string", b: "string"): void function test(a: any, b: any) {} test("", "string") // type s between the ''

drifting sapphire
#

anyway, i agree it's lame in your case

real grove
#

yeah makes total sense

#

my current solution is to perhaps do it generics (less tuples)nand then do the assertion in runtime

#

something like this

#

let me try