New v2.1 arktype matcher: is there a way to match on string literal values?
An example from the docs:
If I try to switch this to a typical string-value based discriminated union, I get an error:
'one is unresolvable' and 'two is unresolvable'
29 Replies
All the syntax is the same as with a normal definition so you'd need to surround the keys with quotes like
"'one'"
figured it out
yep!@
haha, I just realized that myself. It's been a while since I wrote arktypes, have been extremely deep in the Effect ecosystem for a while because that's what we use for all of our services and dependency management
Makes sense and it is definitely a change anyways to have a type parsed in a key rather than a value.
Because the extra quotes are a bit of a pain here I may add a util at some point that just allows you to match against a block of string literals directly
follow-up unrelated question: is there something similar to effect's
Match.exhaustive
that I can use to assert that the matcher is exhaustive?Effect's match has that "block of string literals" utility, btw, not sure if you have seen:
Pretty easy to do a lot with the
.case
API, but I also want to optimize the record API to be as clean and useful as possibler most of the time because it is so concise compared to chaininganother matching question: is there something similar to Effect's
Match.withReturnType<T>()
that allows me to constrain in an arktype Match the allowable return values for pattern expressions?
e.g.
The part I worry about a bit with exhaustiveness that would be unintuitive is stuff like whether
number > 0 | number <= 0
should be exhaustive relative to number
. If you really want to be thorough and accurate about that stuff it might be unintuitive for most people?
No way to do that yet, a good suggestion that would be easy to add though!yeah, it unfortunately gets complicated with type expressions like that ... I am mostly only using it for matching on a discriminated union type, where exhaustiveness checking is easy
Yeah, I just wonder how other matchers handle that stuff without it being unsound
ArkType is very strict about that stuff not being hand-wavy so even if it would be easy to introduce simple shape checks for exhaustiveness, I want to make sure the solution is robust enough that it works well and hopefully intuitively across all constraints
Created this for the few we discussed that I definitely want to implement
https://github.com/arktypeio/arktype/issues/1334
GitHub
Additional match utilities · Issue #1334 · arktypeio/arktype
opt-in runtime exhaustiveness check (maybe default: "exhaustive"?) utility for matching against a record of string literals .out for constraining return type
thank you!
if it would be possible to add simple compile-time checks for exhaustiveness backed up by a runtime check, that would be amazing. (the compile time checks wouldn't be complete, but if they catch the obvious stuff, that would be helpful for development rather than needing you to run the code to see you have an obvious match case missing, e.g. for the simple discriminated union case)
It's not possible to do soundly unfortunately without a huge amount of additional type complexity
Well let me see
Ehh
Ok
I mean I dunno
I'm suggesting an explicitly not sound compile-time check, such that it compiling may not mean it is exhaustive at runtime, but it being not exhaustive at compile time definitely means it is obviously wrong
I dunno if that is a confusing DX though
Basically if the value we're using for the case is a unit type like a string literal that can't be narrowed it should be safe, but yeah in the general case no without inferring subtypes (which as mentioned is a ton of extra overhead I don't want)
Maybe you're right and this does work
That's essentially how parsing already is right? We try to give as much as we can statically and then the rest like
nubmer > 0 & number < 0
is a runtime errorah gotcha. or for e.g. number, once you use subtypes such as
number > 0
, you are opting out of the compile time check, but for simple cases with simple types and no subtypes it could work
exactly 🙂Ahhh right but I remember now the issue I was having
The final exhaustiveness check heuristic would still work, but the sequential narrowing which would be really nice can't work, because applying a heuristic to that would mean you could need to map branches that have beeen incorrectly excluded
can you do a suffix/prefix match without doing regex?
this doesn't work for the first key. basically trying to do like
['string${variableDefinedOutsideOfStringLiteral}']: url => slice(...)
where inside the [], is backticks. was able to get it done with union and regex, but wondering the most "arktype-y" way to do itYou can't do it without a regex as we don't support template literal types yet (not 100% we will as if we can support type-safe regex that will generally be more powerful).
Not sure why you would need a union though
Unfortunately inferring keys within
[]
is a limitation in TS
So that may be causing part of your problemthis is what i've got working
just unfortunate part is i can't embed my constant value, so if it changes i don't get that for free here
This looks like it works:
I think just not being able to compute the value inline is a TS limitation, IIRC @Andarist has worked on some improvements for dynamic keys like that
You could write a fancy mapper that would iterate over your object and map all of its k/v pairs to this format if you have lots of url endings or something
ah i didn't think about pulling out the matcher. this looks good to me, thank you!!
i don't really need anything more fancy, just didn't want to hardcode the suffix value
Cool, I was just imagining if you had e.g. 20 other suffixes like that for different domains you'd probably want some pattern for converting them all
yea that is true. will note down potentially for the future
(side note: this match function is really cool, and making me rethink what runtime validation actually means a bit. didn't consider ever using zod for something like this when i've used zod in the past instead of arktype, but in hindsight it totally makes sense)
It feels really different with how expressive type-syntax can be
Mostly to get people to try ArkType now I have to position it as something that directly parallels an existing library like Zod.
In reality, it handles validation like Zod, but because of the definition syntax and introspectable type system it can also do lots of other things I'm hoping other library authors especially will catch onto
those computed properties are cached all over the place internally :v and it's hard-ish (without major~ changes to the code) to check them contextually somehow
so I gave up on it, given I'm not sure if they would take that change and the time I'd have to wait for a review etc
maybe there is already issue about it somewhere?
with a stronger signal that they could be interested in it I could revive that work at some point
i guess the problem could be that resolving types within such computed properties could lead to new circularities
but it's already a possibility in other scenarios so it's probably fine
Re: stuff that would let me do hacky match stuff with keys, do you think TS would ever consider allowing objects with a narrowed
toString()
type or something to have a narrowed interpolation?
Maybe that is too niche for the team to care hahai'd say it's really niche ;p