extracting redux-like actions from type.enumerated discriminated union
Trying unsuccessfully to convert some redux/reducer-like "action" object types to arktype:
Below is how I did the conversion. The
Extract
on the type.enumerated
results in a never
and I don't follow why.
If I define the action union type in vanilla TS (from the ark inferred types) the extract works as expected:
Am I holding it wrong?45 Replies
Enumerated is array.includes, not a union
You need A1.or(A2)
Lemme actual rewrite your code
are you sure? because when I look at the resulting type of the infer on the type.enumerated
type ArkAction = type.infer<typeof ArkAction>
it looks like this:
https://github.com/arktypeio/arktype/blob/da2f08d559e7c9a8e95ca513227a1496f9be3041/ark/type/__tests__/type.test.ts#L126-L130hm, it does work
It's for
const typeValue = type(['===', 'ACTION_1', 'ACTION_2'])
i.e. for enumsyeah i basically have an enum though, right?
No
A enum of
let a = {}, b = []
is [a, b].includes(v)
, not [{}, []].includes(v)
as different object instances are not equalahh
ahhh
right
===
ok got it
So you are checking if your object is one of two ArkType instances lol
ahhh
ok ok, thank you that makes sense
BTW how do you think it should be named?
The make union one and the make array of values one?
I do not feel like it's named perfectly so what would you guess they are named if you never used ArkType?
May be more then one variant
May be inspired by other validators
enumerated is ok, that's actually how I assumed it worked previously
and
.or
is fine as well
totally
though I'm not keen on the chaining@ssalbdivad we need
type.oneOf
or type.discriminatedUnion
equivalent as I expect peoples to want a way to avoid .or
chainingtype.union
?Yes
And I want an AI type generator on the AT page (╯°□°)╯︵ ┻━┻
"Paste your code here to get the right (darn I forgot the word again) ArkType defs"
and/or make
.or
take multiple arguments e.g. .or(...types)
typebox-workbench gets you some of the way there:
https://sinclairzx81.github.io/typebox-workbench/?share=dHlwZSBUZXN0QWN0aW9uMSA9IHsgdHlwZTogJ0FDVElPTl8xJywgdmFsdWU6IG51bWJlciB9CnR5cGUgVGVzdEFjdGlvbjIgPSB7IHR5cGU6ICdBQ1RJT05fMicsIG5hbWU6IHN0cmluZ30KdHlwZSBUZXN0QWN0aW9uID0gVGVzdEFjdGlvbjEgfCBUZXN0QWN0aW9uMgoKZnVuY3Rpb24gQ3JlYXRlVGVzdEFjdGlvbjEoKTogRXh0cmFjdDxUZXN0QWN0aW9uLCB7dHlwZTogJ0FDVElPTl8xJ30%2BIHsKCXJldHVybiB7IHR5cGU6ICdBQ1RJT05fMScsIHZhbHVlOiAzIH0KfQoKY29uc3QgdGVzdEFjdGlvbjEgPSBDcmVhdGVUZXN0QWN0aW9uMSgpIA%3D%3DWell, it works fine
Why don't you just use its output btw
I don't like the strings
string definitions???
refactoring
explain plz
too much magic for me
ah, renaming constants?
for example
Well, but they are pretty powerful
yeah, if i rename something via the editor, I don't want to have to think about whether I have a string somewhere with the wrong name
But that's the point of ArkType 😭
lol
Hmmmmm
You can't rename literals
And renaming non-optional values does work
@errata try to learn the string way anyways, as it has looooots of features
e.g. you may want
'0 < integer'
typeright but
'TestAction1 | TestAction2'
Well, yep, this thing in scopes is not pretty
But it allows recursion so eh
yeah I'm using that kind of syntax for validations on primitives
no lost functionality when used for that kind of thing
i.e. I'm using ts in the first place because I want things like refactorings to be no-brainer operations
though, the compiler will error and I won't be able to build a broken app, even if I do have some strings to rename
which is good
(so long as I don't do something like swap the names of compatible types)
As you say, there are already a lot of definition types, each of which I think is ideal for some situation.
Adding helper methods for union/intersection etc. as an alternative to chaining feels like adding another for extremely marginal value.
You do need a union helper for when you have 10s of discriminated items
e.g.
Event
tl;rd add it next time someone asks how to union 10+ itemsA huge benefit of the type system is not having to manually discriminate
I mean this
The entire benefit boils down to writing
,
instead of .or(
I'd guess enum, since TS uses
enum
+1
enum
or literal
Also you could just define that as an object
Well, yes, what do I do to union values?
o.get(o.keyof())
Okay that's fine
But you need to doc that
Right like
enum
is not an overloaded term that causes confusion in TS lol
Above all else, I want to make sure my names don't create bad intuitions.
Stuff like .unit
instead of .literal
I get is less intuitive for people coming from Zod, but it's a much more unambiguous description of what kind of type you are creating once you learn the term.Ah, right 👍👍👍
As discussed in the past,
{}
and []
are also literals and I'd likely expect they would be checked for deep equality based on that, not using ===