Is there a way to mix values and types in such a way that they are resolved by the compiler? #7520
Unanswered
adamscybot
asked this question in
Q&A
Replies: 1 comment 1 reply
-
Not helping your right now but that is something that feels like could get resolved by this proposal #6322 which is basically your suggestion. You might be able to do that yourself with forking hte json schema emitter and defining a custom scalar in this form but it will be quite nasty due to we don't allow template instantiation directly in member expression yet. @trackType(T)
scalar foo<T> {
init create();
}
model Bar {}
// Need this to workaround the fact you can't use that directly next line
alias C = foo<Bar>;
const a = C.create(); Going the decorator approach is probably going to be simpler and let you simplify the structure to your liking @propertyDiscriminated({
and: AndSchema,
or: OrSchema,
not: NotSchema,
}) and let the decorator fill in the if else. edit: probably wouldn't even do that just rely on the union variant themself. |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I am finding myself in need of a form of conditional schemas, which has eventuated a more granular question. My schema is advanced -- it is recursive and the json input is a representation of a language of sorts. I am using the json schema emitter.
I am aware of #6772, but I am wanting to do this today through whatever escape hatch possible in the short term, no matter how dirty. Its also worth noting that my use case for conditional schemas is a whole lot more narrow than the possibilities it can open and conceptually, it is representing a statically analysable concept. So its not that gross to imagine in typespec.
I don't want to dwell too much on why I am wanting to do any of this at all, but I will a little for the sake of clarity. Essentially I have a union of schemas, where each of those schemas has a single property of a different name. E.g.
{and: AndSchema }
,{or: OrSchema}
etc. That single property is in itself the discriminator.oneOf
works fine in terms of correctness, but the error messaging is terrible in the evaluators I've tried. If you do{and: 'example invalid value'}
you will also receive irrelevant validation errors relating to the evaluation of the other schemas in the union. I am aware this would be expected withoneOf
andanyOf
, hence my need.Using conditional schemas as a way to represent this "special" union works perfectly in my case, in that it declutters error messaging. I have tested this outside of typespec and it solves my case.
So back to typespec. I was hoping to do something ugly like this.
I was very pleased to see the reference to
AndOp
etc is resolved to a$ref
object in the resulting schema. That is is something I've needed so many times for these escape hatches. However the other raw data (theif
) part, which I want to be inserted literally, is instead interpreted as a type itself.It was at this point I realised that if I use
#
anywhere to denote a value, then I have to use it all the way up to the root of the object literal. And if I do that I lose the magic$ref
in the schema output. I could manually write the string identifier...but thats dirty for obvious reasons.I wanted to ask here as its not the first time I've wanted something similiar, and possibly I have missed something. This case and those that I have witnessed before could probably be fixed if there was some way to "serialise" or "resolve" a model to a ref using some new construct. Pseudo code but...
Something like this that somehow converts it to a value is one potential solution.
Perhaps custom emitter code is in order (something I've done in the context of a totally new emitter in the past). But I wouldnt want to rewrite the whole JSON schema emitter, and I'm not sure if the standard one is extendable in such a way that I can add to its feature set.
Maybe a sort of hands-off extension could be done by introducing a new decorator that calls the existing extension decorator with the model resolved to ref somehow in the implementation?
Beta Was this translation helpful? Give feedback.
All reactions