Not to be flip, but if it were really all this easy, we would have done it already.
There are dozens of questions you can throw at this code: What if the input's a union? What if it's a nested union -- how do you avoid combinatorial explosion? What if the input is a function -- how do you validate its parameter types using runtime information? What if the input is a conditional type? What if you're inside a generic function? The list is enormous and it quickly gets into "you've dug too deep and unleashed a Balrog" territory once you get beyond the primitives.
Why don't you just make the transformer API stable, public, and let the community do the hard part? There's plenty of us that have experimental transformers doing all sorts of fun things, these are problems that can be solved external to TS.
I've got a fully functional compile-time dependency injection container that I've been sitting on for literal years because the transformer API isn't public.
^^^ Please do this. I'm completely ok with "using transformers voids your nonexistent warranty" and the community can deal with transformer API churn. Exposing the API makes it easier to adopt those community solutions, versus me needing to explain to teammates why I switched all the `tsc` invocations to `ttsc` and promise it's not that sketchy.
(So as it turns out having thought about it a bit, I am vehemently against this idea.)
Type reflection at runtime would require polluting the JS environment with a lot of cruft.
That might be a global object and lots of helper functions to query types. It might also be tagging objects and fields with additional properties that need to be treated as reserved.
There is certainly no way to do this that doesn't make assumptions about the runtime environment in a way that will cause a mountain of issues further down the line.
The other reason for my disdain is: the need to infer types at runtime is almost certainly indicative of an architectural issue with your code. If you aren't able to write viable code in a given context without requiring runtime type querying then you should step back from your intent and re-evaluate your code structure.
I mostly agree, having every single type checked all the time like other static languages is not appropriate and probably not even a good idea but on the other hand it is also kind of annoying to have your validation code be divorced from your types totally.
For example suppose I have a web request coming in and I have essentially just a string of input coming in on the body. I have an expectation of what it needs to be but there is a step where it is of type `unknown` and I need to convert it into `IMyHandlerInput`. Just casting it is obviously a bad idea and so now I need to essentially use some kind of library such as ajv to do json schema or jtd validation, _then_ I can cast it into my interface.
This is all fine but it definitely feels redundant to me. It would be a cool _ecmascript_ feature to essentially support, not runtime types per-se but syntactic _validation_ which can also be used by typescript to derive types automatically.
This is totally hypothetical but I'm imagining something like this for example:
```ts
schema Example {
@min 0
id: number
@pattern /^\w+ \w+$/
name: string
@future
expiresAt: Date
}
const data: Example = new Example(JSON.parse(body))
```
Something that the JS runtime can use to allow developers to opt-in to extensible validation which can also be used by the typescript interpreter to essentially derive types.
Maybe I'm very mistaken, but to me it seems this code snippet is basically an alternative to writing a ton of "infer"-s and overloads, no? So the same pattern matching could be used in the "switch". Whatever the complier knows can be locally matched, and the combinations have to be already handled by the developer.
It's hard to come up with a compiler that produces a sound checker for arbitrarily complex union/intersection types. Perhaps there could be a restriction on reflection to "simple enough" types, but that's always going to be a weirdly moving target based on heuristics. There's already cases where Typescript tries to generate ~40MB+ .d.ts files which are just re-stating the types themselves. So it's easy to imagine a validator compiler emitting 100MB+ of code to check more wild and crazy types.
Size, computation and other budgets seem like useful knobs to expose to developers. And anything that's locally decidable (so can be run on multiple cores easily).
There are dozens of questions you can throw at this code: What if the input's a union? What if it's a nested union -- how do you avoid combinatorial explosion? What if the input is a function -- how do you validate its parameter types using runtime information? What if the input is a conditional type? What if you're inside a generic function? The list is enormous and it quickly gets into "you've dug too deep and unleashed a Balrog" territory once you get beyond the primitives.