Closed joleeee closed 1 month ago
Whats strange to me is that a type string>3
can have default "a"
, which is definitely not string>3
, but it cannot be null
even though null
is also not string>3
...
I tried working around this by creating a null
type but narrowing it down to not be null
. Unfortunately arktype is a bit too smart for this workaround:
const notNull = type("null").narrow((value, ctx) => {
return ctx.mustBe("not null :)")
}
// ParseError: Intersection of null and $ark.fn8 results in an unsatisfiable type
Default values don't have to be valid, they only have to be the correct type for the schema data.
The convenient way to have an empty field for a non-nullable property is to use a proxy: https://superforms.rocks/api#proxy-objects
Yes so you can use the proxies to have null
instead of ""
for instance, but there is no way to avoid putting a | null
or | undefined
for every field in the schema?
There is no need for that when you use a proxy.
Sorry but I don't see how 😅
In the example from above, what do i put in the default? I don't want to set a default. I don't see how the proxy fixes this, as that is for the client side?
export const flightSchema = type({
date: "string",
})
export const flightSchemaDefaults = {
date: // what do i put here
}
You can try new Date('')
to get an invalid date, but I'm not sure how the date input (or the proxy) reacts on that.
If your date is a string though, you should be able to use an empty string.
I guess it works for strings that way, because "" is kinda invalid. What about if instead of it being a date, it is a number. Maybe you can use NaN
or something. Still, "" is a valid value, and NaN
is a valid number, so the schema will be able to submit, except if you manually add a .narrow() or proxy to "" -> null
(only client side, can still craft a response with ""
).
But what about some other type where there is no inherit "invalid" value. I have a bigger example here which is real:
export const airport = type({
id: "number",
icao: "string",
iata: "string",
type: "string",
lat: "number",
lon: "number",
city: "string",
name: "string",
country: "string",
loc_id: "number",
});
export const flight = type({
date: "string",
from: airport,
// 15 fields removed for brievety
})
export const flightDefaults = {
date: "",
from: // what here
}
The user can select an airport and all the fields get filled. But what about when no airport is selected yet? I cannot do from: null
because null is not airport
, and I don't want to do airport.or(type("null"))
because I don't want you to be able to submit with a null value. Do i just have to manually setError
if it is null? It feels so wrong.
Then you need to constrain the fields so the default value won't be valid. For example, city as just "string"
will allow an empty string, a string with only spaces, only punctuation, etc.
In case you haven't seen it, here are the default values added to non-optional fields without a default value: https://superforms.rocks/default-values (except for adapters like Arktype, since the default values must be explicit.)
This kinda works
export type Airport = typeof airport.t;
export const flightDefaults = {
date: "",
from: null as unknown as Airport,
}
I think my thoughts can be summed up in that I think there should be a way to have default values which are invalid (and different types) than the fields they are going to be in.
Invalid default values with the same type is no problem (empty string with validators that doesn't allow that), but different types aren't possible, since that would break type safety. You need to cast it yourself with as unknown
(or use a proxy on the client).
Description I think, with the current way that defaults are required, it is not (easily?) possible to have a form where certain fields must have a value, but shall remain unfilled.
I have a form where among other things I have a date field. This is required, but using superforms + arktype, I have to specify a default. I don't want there to be a default...
The best workaround I have come up with is to have a separate schema which has the
| null
, and then use this on the client, but validate server side with the proper one (no| null
). Is there a proper way to achieve what I'm asking for here yet?FAQ says:
I cannot find a tracking issue here or in the arktype repo for this functionality.