Mapping types
Hello, is it possible do to code like this?
And if so, is it possible to also inherit those types while mapping in logic, like so?
89 Replies
You can merge two types like this:
It works just like spread in JS
You'll have to explain more about what you mean for
c: Number(original.c)
Merge could be used for the first example
Well, lets say that I have a transformer like this
This takes in X, and returns Y, where the only difference between X and Y is that c is of type number, not string
I wonder if
A. Arktype has these transformers available somehow
B. If they represent the output types correctly, according to the returns of the transformer
Are you wanting to transform only between two types, or do you mean that you want a type that takes in a string and converts it to a number?
Between two types, X and Y, and it figuring out automatically that Y is supposed to have c of number, not string
But still keeping all the X fields that arent c
Isn't that what the first example would do as well?
Well not really, because I'm telling that first example the exact type
But the second one is deriving it from the functionality and the original type
Maybe if you can give an example where something other than
Number
is occurring because I don't really see how anything is being derivedWhile Number(original.c) is a very simple and straight forward example, there may be much more complex transformations that I can't derive in my head
Sure
Ohh I think I see what you mean you want to be able to access the prop of an existing type
The best way to do that for now is to define that prop as a standalone type and reference it in both places, then you can transform it one of them which is a good practice in general as if you're wanting to reuse it, it's generally best it's defined with a clear name in a reusable way
There will be index access types soon but not yet. Also native map syntax that matches TS is planned
And if userWithAutoEmail could be also called as a function that actually maps it, that would be perfect
If you want to add a comment to https://github.com/arktypeio/arktype/issues/584 with an example/suggested API that will be helpful for when it's implemented
GitHub
Mapped types Ā· Issue #584 Ā· arktypeio/arktype
I created the following props rule type to support intersections/unions and eventually checking types whose values are dependent on associated keys. Some parts of this may end up being out of date,...
For now would recommend splitting up anything you want to reuse though!
I'm mostly asking this because of this TS issue
Which I thought could be fixed by ArkType actually being a little smarter than plain TS
Maybe in some cases. It's good with cyclic types but obviously some aspects of TS we have to work within. Will be interested to see!
Okay update, I have been pointed to using Zod or Arktype for my issue on the Typescript Discord, exactly as I wanted :D
Haha, I don't think he likes ArkType very much IIRC š
Do you have any ETA on when that "mapping" syntax is going to be available in ArkType?
Hopefully within a few months. The first priority is to get all the 2.0 features documented and to finish generics + pattern matching
But once generics are done it should be a relatively clean abstraction on top of that
Even though they're less fun I also have to prioritize stuff like generating JSON schema/ open API integration etc. because that is what everyone asks for
LIke I said though add a comment to the issue the more feedback I get on stuff the more I will prioritize it
I'm not sure if I used to word correctly, as the issue you sent me is talking about "mapped" types, where I'm more interested in "transforming" and getting its output types at the same type
So both runtime and typescript level
Well that is what mapped types do right?
Everything in arktype is both at runtime and TS level
I'm not sure
I'll have to think about it some more
Only if Typescript could include such an obvious feature as recursive datatype inheritance... well
There is a very general transform API that gives you total control over mapping all the types nodes in
@arktype/schema
but that is a more advanced feature and it wouldn't be possible to infer from that API
But I use that internally to e.g. prune checks that have already been discriminated from types, so in terms of the runtime values it is very powerful. not ideal for what you are talking about thoughYeah I can imagine it would be very sweet to have some kind of syntax like this
Pure TS
ArkType
As in this example I'm not duplicating ANY information basically, compared to pure TS approach, where I have to describe the types and the logic too, when the types could be easily derived from the logic itself
And also if I could somehow get a type verifier from AtoB or BtoC for free, that would be amazing
Okay but it really seems like you are talking about piping the values after they've been validated
So I could do like
And it would do a normal type check like arktype does
Not just transforming between types
Which is much easier
What exactly is the difference there?
Something like this:
You can pass arbitrary transformations to
pipe
including other types and it will infer/validate them
It won't apply them as generics though as that would require them being defined as HKTs
Is that legit?
Oh wait, no, it uses the validation afterwards in the second argument, hmm
Right but that is what you expressed in those examples
You might need to think through exactly what you want a bit more. But piping is much easier than arbitrary transformations in terms of only the types like mapped types
You are right, thanks a lot for the patience, I'll come back to this thread if I come to some conclusions
No problem this stuff is tricky to think through! Will try to provide the best APIs so your types are as flexible as possible both to transform and to pipe š
It's
.pipe
in v2
You also can't parse definitions inline with that syntax the way you could with outValidator
as the second param
So you'd have to define the second param is A.and(E)
Is there a generic pipe? (
Type<T>._generic((t: Type<T>) => Type<<G<T>>>)
)?No haha, we'll see what APIs I add once I add generics
That looks pretty decent
Even if it looks very unintuitive, it could get the job done
It's possible to make an intuitive wrapper a la
I'm more interested in the AtoE function, as the fields are going to be all inherited, either through explicit assignment or
return { ...original }
But that requires me to define the type E, which is not something I want
I would like it to be inherited from the transformation on A itselfYou have to write the type to validate it
Or you don't need validation?
Well, I would like it in the future for testing
Well, you can
But generating a "transform" function and "validation" function at the same time just from inheriting the transformation output would be GOATed
Btw you may make it infer E from function and then write the matching definition (with ArkTypo errors)
Does that not failt at this problem tho?
You have to write the type
If you click on function and it suggests "infer return type from definition" you sorta have written it already
Hmm
Lemme reread the question
Yes it fails, you have to write the validation yourself (if you need it)
@ssalbdivad eslint --fix rule for
type.for<T>()
when š¹What is
type.for<T>
?
To autogenerate the definition from the ts type? I know @TypeHoles was working on somethin glike that for a while@JameEnder Wasn't the original question just this?
Unknown Userā¢7mo ago
Message Not Public
Sign In & Join Server To View
Yeah I meant the editor integration for the workbench.
Assuming the goal was to get the AT def from the TS type couldn't exactly be done in real-time anyways
Oooh, having the fields as pipes is a very interesting idea
But sadly the fields dont correspond to the field in the output, and there are some that are created from deeply nested properties of the original
Even so you could do something very similar at the top-level of the object
It is better to have them within a field when you can but if not you just move up a level
I think this whole thing is not possible with ArkType either, as it is an issue with the whole Typescript library itself
And it's inability to describe function / transform outputs that are recursive
Yeah it really depends on what you're trying to do haha
I really wish I could show you the actual code that i need it for, but NDA :(
Ahh well
I'll try to write up a similar example that doesnt leak anything
If you're wanting to infer return types of recursive functions then yes in a lot of cases we're stuck with what TS can do
But recursive generics work in terms of inference so who knows maybe there are possibilities
Especially with HKTs
I see. Definitely feels like more of a static analysis issue than a runtime validation one
And what I expected TS/AT to do is to infer the type as
It would have to create an anonymous type for that recursive result
But yeah
Yeah, most likely, I mean runtime validation was a thing I wanted to do also, but now that I'm thinking about it, if its not possible in TS itself, it wont be possible with AT
It's pretty easy to just adapt the type to what you need and type the return explicitly at least
Not when there is like 30 fields :D
I mean its still not like difficult
It's just annoying having to repeat myself, when the compiler already knows every single type there
And if I wanted to have the type be able to adapt to the input field types changing, I would have to use this insane syntax for it
Which I don't think I will, as there are like deeply nested turnaries and ugh
But thanks a lot for your help! <3
Good luck!
Hmm, so you need JSON restructuring?
I mean, I need object restructuring :D
With ability to infer recursive return types of a function taht does that "restructure"
I think in most cases like this you would want to have an explicit type for the return- it would be weird to have that function be the source of truth for a type like that
Restructuring is a COMPLETE DIFFERENT PROBLEM ā¢ļø
š¤
Also because at best TS could say:
* from validation
I mean it's kind ofa nothing problem for the most part any abstraction you make beyond just having a pipe API that allows you to reconstruct the object using normal syntax is going to be a mess
Well not a mess
But just needless complexity for something that can already be expressed with the language
JSON I mean as a "plain js object" here (w/o classes dates and Maps)
I mean, couldnt it just create an anonymous recursive type and include it in the definition?
Got you
Right or that. Referencing the return type would be at least a little clearer there IMO than
...
or notoriously if you have noErrorTruncation
on it shows up as any
But I'm just saying that type really isn't defined anywhere else you just construct it there from that function and then reference it elsewhere?@ssalbdivad can you use
this
for superobject in inline morph?
(i don't have an idea I have a feeling)I dunno either but this won't work until generics work
@JameEnder I can imagine remap but this is hard lol
The only advantage would be that we'd have the runtime definition of the output type
I'm very confident whatever other custom syntax you'd create to do that would just be more confusing than mapping/mutating the object with a pipe
That's not remap at all that's just index access on a type definition
And
remap
is just type
I'm imagining fn-like api for JSON restructuring
Well you do you I'm just predicting that would turn out badly
I mean this would be a completely fine definition by me
And I find it better than just throwing "any" out of the function
It's an error though they just require you to explicitly type it
Yeah I agree inferring something would be better but I get why it's not a top priority usually you'd want to have a type like that defined somewhere anyways
That's so cool š©