Extending types similar to an interface
How would one go about extending types similar to how one would extend an interface in TypeScript? It's really the only thing I feel like is missing for ArkType to be a viable alternative.
A minimal example of what I want for ArkType, but written in TypeScript:
53 Replies
You can do something like this:
If you really need it to work like interfaces, you can do this:
https://discord.com/channels/957797212103016458/1162539860574347385/1162722103959760926
You can chain
.and
or .merge
depending on the behavior you want. Instead of manually typing the keys as never
, you can just add "+": "reject"
on your object definitions to specify that no undeclared keys are allowed.I guess my question is more related to discriminated unions from a DX standpoint. I find myself not being able to declare types as I mostly do in TS with ArkType. And that's the only reason I can't adopt it.
You can literally write:
What could be more similar than that š
It is similar, but it's not enforcing a constraint, you could merge with a
kind
not related to the original type.I guess you want
.and
If the types are disjoint for a non-optional key, it would throw a parse error
But the second still wouldn't have to be a subtype of the firstIs there any way to make that work within ArkType?
Or is it planned?
Yeah there are lots of ways one sec
Something like this would be one way, although it would require a full subtype (not missing props):
It would be pretty easy to build a utility function or something that would iterate over each prop and check if it's present instead if you wanted to do that.
Personally I think there would be better ways to express these kinds of relationships in general. I'm not sure I'd add the exact equivalent of
interface extends
to the API when and
and or generics can be used to do something quite similar, but I'm open to considering it more. The implementation would be fairly easy externally anyways, so really a matter of whether it convolutes the APII'm assuming this would break if you had nested discriminated unions
Why?
Another option that would give better type errors if something is incorrect for a complex constraint like that would be something like this:
You could change it to accept a validated definition so you don't have to wrap it in
type
with some extra workI don't think I understand
Could you give an example of nested discriminated unions, similarly to how you would do in TS?
I don't know what you mean you can just do whatever you'd do in TS the same way:
Keep in mind internally arktype always discriminates unions for you so you'll get those optimizations for free without having to do anything special
Including nested discriminated unions
is there a way to have kind filled automatically. I tried pipe, nothing works for me
You will have to be more specific haha
in this example I assumed that s will have kind set to 'series'
I need kind to default to 'series' in SeriesTitle
Have you read the docs on default values?
I've read all the docs twice ... hehe ... but let me recheck
You read this?
https://arktype.io/docs/objects#properties-defaultable
I just did
Does that solve the problem?
nope
ā ark git:(auth) ā bun test.ts
error: kind must be "episode", "movie" or "series" (was missing)
Oh I see what you want. Well
and
means all the constraints of both types have to be satisfied, so you can't intersect something with a required key and get an optional key (or a defaultable key)
You should remove kind
from BaseTitle
or make it optional there
You can also do that after creating BaseTitle
using .omit("kind")
, but it's kind of an antipattern in that situation. Best to just build up the type with the shared propscool thanks. so many gotchas. I guess it is because of typescript.
Yeah, that's based on TS but that one actually makes sense according to the underlying set theory as well. It gets tougher when I have to figure out to do with stuff TS gets wrong without breaking compatibility haha
here is my temporary conclusion. cuelang typesystem is far ahead of anything i ve seen. And I used so many languages.
I think it's good to keep as a benchmark. just my 2 cents.
Haha you have to learn more before you can make judgments about that. There are some areas where TS really shines, e.g. enabling a library like ArkType to give such strong type safety and completions
You aren't at the point yet where you have good intuitions about set-based types. TS does have its weaknesses, but it has some really significant strengths as well.
do you know cuelang ?
No, and so I will reserve judgment about that. I'm just saying I've talked to lots of other devs who work with lots of languages and never heard anyone say TS has a weak type system. Idiosyncratic and unsound? Yes, but like I said, you can create APIs with it that are really rich and responsive in a way I haven't seen in other languages, at least without macros or custom editor extensions
since you are busy. take a look here:
https://cuelang.org/docs/tour/basics/types-are-values/
cue is JSON supeset
Most of what's on that page exists in TS and all exists in ArkType other than negated types. What makes it so good?
what make it so good, is less rules. smaller grammar.
easier to read
Narrowing done right.
It's easy to read because you're familiar with it haha.
no come on !!
hehe
you can read the doc in no time
hehe
I did read some of the docs though. Shares a lot of features with ArkType, plus some specific syntax for computation like comprehensions.
I'm am curious about the underlying type system- how unions, tuples and intersections are reduced. To me that is the pinnacle of what makes a good set-based type system- the ability to reduce and normalize so that any two types can be accurately compared.
Saw some cool tricks with cyclic references but they feel a bit more like a party trick. At least the ones I saw haha- e.g. it being legal to define a scope where
a: b
and b: a
since everyting is a value in cuelang
you can merge any two type sets.
you can merge a string and a value to a value if they dont conflict
cuelang is not turing complete. so it's a specialized tool.
it's also order independent
Have you tried intersection logic in arktype? merging a string and a value is one of the simplest things it does hahah
Haha check out tuple intersection tests in arktype... slightly different level of complexity š
E.g.
The prefix + postfix one I think is especially cool as its the only intersection I know if that splits into a union
let me convert it
If it can represent and reduce the prefix + postfix case I will be blown away and immediately sold
Cuelang's description of unification though is exactly the core principle of ArkType I mentioned so it's cool to see the alignment there.
ArkType is extremely rigorous about that process- intersections that result in unsatisfiable types will error and we can compare equivalent types like
number[] >= 3
and [number, number, ...number[], number]
even if they're represented differentlycan you please provide the simplest example from that code ?
Do you know how variadic elements in tuples work?
...number[]
means an arbitrary number of consecutive number elements
Not sure if that is a feature or notyes
// A is an open list with 3 predefined elements.
// Any additional elements must be ints.
A: [1, 2, 3, ...int]
Lists: https://cuelang.org/docs/tour/types/lists/
Yeah but they only support trailing rest elements and no optional
So types like those from my example can't exist in the first place
The more I see of their docs though it really does parallel arktype in a lot of ways in terms of these reductions.
If the underlying type system just can't represent as much it's hard to compare the unification
so you what a first and a last element and some stuff in between ?
That's a variadic element. There are also optional elements in TS/ArkType which is a single element that may or may not be present
In ArkType they are called prefix, optional, variadic and postfix
wow !
do people use this stuff ?
Advanced users mostly, but yeah. Like I said you're definitely underestimating TS before you get to know it š
I will say though even though ArkType mirrors TS, the philosophy of the type system itself is much closer to Cue
I'am a proponent of least design principle
There's a lot of overlap for stuff like intersecting ranges which is really cool to see
I do build apps not libs. so I tend to go with simple designs.
so that I can 'show' code to business people
it's kindof a lowcode mindset
Yeah I think not cooking too hard for app code is probably good haha
ArkType is complex internally but the goal is to make things as simple as possible externally which hopefully is a good trade off
I guess it's the workaround for Variadic lists.