Can I add a default value to a type if everything other satisfies in a union type
const type1 = type({name: "string"})
const type2 = type({city: "string"})
const union = type1.or(type2)
const result1 = union({name:"ankit"})
const result2 = union({city:"Ajmer"})
I want result1 to be {name: "ankit",kind:"name"}
I want result2 to be {city:"Ajmer",kind:"city"}
or better
const [kind,result] = union({name:"ankit"})
here kind will be "name" and result will be {name:"ankit"} and kind type will be "name"| "city"
can I add these default value of kind in the type definitions so that if parsed with that validator from the union the kind is added
33 Replies
You should be able to union morphs
If they have incompatible inputs
What if you have {city, name}?
š¤
@aabad_ankit
Wait @ArkDavid wtf is
removednull
@Dimava the Monoreaper If I try this
1. merge is not available on baseType
2. I am not getting the name in the result, it seems the pipe operation is applied in the end
You can't apply structural operations like
merge
on a morphed type. For now at least, I'd just create a unions of the inputs then manage the discrimination logic in the pipe implementation from the unionGitHub
How should you
.pipe
to a type constructed with or
? Ā· arktypeio...I have the following: const objSchema = type({ action: "'scheduled' | 'rescheduled' | 'canceled' | 'changed'", id: "parse.integer", calendarID: &...
It would be theoretically possible to discriminate using strict key presence but it's not implemented yet:
https://github.com/arktypeio/arktype/issues/786
I need to learn a lot š . This library is just awesome.
Thank you š Working on more docs now!
docs will certainly help.
@ArkDavid How can I get better error msg for this
prints "name must be a string (was missing) or city must be a string (was missing)"
since age is already there shouldn't it just say "name must be a string (was missing) "
That would require the issue I mentioned before where key presence could be used as a discriminant
If you want total control over how the error messages are handled you could use
.narrow
and create them yourself
If you had a discriminant key like kind: "person"
kind: "city"
or similar, it would check that first, then give the error message based on the branch it is on
It could theoretically do that based on key presence once that issue is implemented
Oh I guess in those cases you don't have onUndeclaredKeys
at all though
So the reason it would give both is because it is true that {city: "foo", age: 12}
would also be valid
Seems to be missing an "or"
, will fix that
But wait null
isn't even allowedWhoops found it
I am getting
name must be a string (was missing) or city must be a string (was missing)
for both the code snippets below.
and
That is expected, it's validating the input not the output. Adding a
kind: "city"
after it's already been validated wouldn't change anythingOh Yeah, Understood š
@ArkDavid @Dimava the Monoreaper What will be the most idiomatic way to do the validation for such union types to get correct error msg. Do I need to check for the properties and do validation by creating a validator map
This is getting verbose.
I am giving example of just one field but my inputs are larger and I have 5 different types of input. If I could have done union then I would have declared on deepUndeclaredkey("delete") on just the union as well as the pipe on the union
What is the actual problem you are having?
This prints
age must be a number (was missing) or city must be a string (was missing)
. I just want the error msg to be age must be a number (was missing)
to do that I am currently doing something like this
so I wanted to know if there is more idiomatic way to do thisUntil there is built-in discrimination based on key presence, I think I would write a custom narrow that checks which special key is in the input, then just invokes that type
That seems somewhat like what you are doing but I'd probably write it as a wrapper that accepts a list of types then creates that transformation internally
Also built-in key presence discrimnation I guess wouldn't work if you have delete for undelcared keys, only strict
(not that it matters yet because it doesn't exist)
but delete on undeclared key will work on union right once you have built in discrimination based on key presence
I don't think it should. This is kind of fuzzy territory since it includes transformations but if I say I have some type it is allowed to have arbitrary additional keys and they will be removed, it doesn't seem safe to use arbitrary additional keys to discriminate
Because keep in mind, discrimination means you are skipping all other branches of the union
But those could be valid and just have some keys deleted
Unless it's actually
reject
@ArkDavid btw can you declare a prop as
prop?: never
?Yes
@aabad_ankit you should use it for now
That is a good way to create a discriminated union on key presence that TS will respect
a code sample will be super useful
I don't think it will help you because it would still not be used as a discriminator even though it could
Why, it should
Like in practice it would eliminate that branch of the union yes, but right now the only discriminants are two required paths that have differing literal values or
typeof
Because the cases I mentioned are wayyyy more common and they are also much more efficient to traverseNever has typeof undefined?
But it's an optiona lkey
You can't use optional keys or paths including them to discriminate
Ah
And you can't make it required
Except in that special case for key presence
Yeah there are several other cases where internally, we know branches are disjoint, but we don't actually transform them to discrimnated union because it's either very niche or a lot less efficient to extract or both
Like I said about the ones we have now,
typeof
and literal values can be checked in a switch in constant time
We could discriminate on ranges like type("number > 10 | number < 0")
because they are disjoint, but we can't write a switch-like statement to traverse the union in constant time so we don't do it (yet)
I'm not sure if it would ever be worth it to consider using range as a discriminant in practice, but key presence I definitely want to do eventually with reject
@ArkDavid You were suggesting to use narrow, can I do it on union and solve my problem
I have to focus on next release now though lol
Actually wait let me improve the error message require quick
Okay this should be good
Actually wait let me improve the error message require quickSee WTF is this I meant to write real quick and wrote require quick? CC @TheStockBroker
Thank you so much for all the help