-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Why can't this feature do type checking at runtime? #205
Comments
In short, it was decided against because it would mean that JS is responsible for defining and maintaining a type system. It looks simple enough with simple cases, like "x: string", but then you get into subclasses, generics, covariant and contravariant type variables, type functions, etc. It's a huge undertaking, much larger than just allowing the annotations themselves, and it would mean that the type system also ends up with the same back-compat constraints as the rest of JS, rather than allowing tools to experiment and upgrade over time. |
This comment was marked as spam.
This comment was marked as spam.
Tell that to Python, which has a thriving ecosystem of type annotation tooling that is also completely meaningless at runtime. |
@DonaldDuck313 I thought, there could be a switch similar to use strict 🤔
@tabatkins But these wouldn't have to be added right away, would they? |
I agree, but you could just as easily be listing all the additional information you need to know before the basic syntax has the same meaning to the person who wrote it as it does to the person reading it. This is not possible, because the person reading does not have any information about what type system the types were written for. If I say "I am going to eat this sandwich," but to me the word "sandwich" means "baseball", you might think upon hearing this that we have communicated successfully. You'd think that right up until you saw me eat the baseball (after all we are using the same syntax). |
Of course this is all premised on the idea that the goal of language is to create communication. Without creating communication the creation of language is impossible, and with the establishment of communication the creation of language is inevitable. Darmok and Jalad at Tanagra. |
Yes, just like in Python (which has multiple typing tools that use similar, but not identical, syntax and behaviors, particularly for the complex stuff like what I listed), you have to know what typing tool the code is using in order to understand that code. This is not, in practice, an issue. (It's usually MyPy, occasionally PyType, checking the CI or the project metadata generally makes it obvious.) |
@tabatkins Can you explain to me how you see this as bringing value to JS given that we already have type systems? |
Another part of the reason I stand in opposition to this is that I sense that it is on some level a reaction to poor tooling design, which I do not feel is grounds for changing the language (but rather for changing the tools). |
We do not have type systems in JS. We have separate languages that compile to JS which have type systems, but cannot be executed as JS. The parallel for Python would be if we had TypeSnake, which wasn't valid Python, but running MyPy would generate Python files from the TypeSnake and drop them into your project folder, where you could run them. |
That much seems obvious to us both. Might I repeat the question? Given that we agree that derivate typed languages are not themselves JS, what is the benefit of this proposal to JS? |
That is what the opening parts of the README for this repo cover: https://github.com/tc39/proposal-type-annotations?tab=readme-ov-file#motivation-unfork-javascript |
This comment was marked as off-topic.
This comment was marked as off-topic.
Again, I see NO benefits described in that section for JS or JS developers. It claims the benefit will be "unforking" the ecosystem yet the JS ecosystem is not forked. Thus this proposal effectively does the reverse of what it says on the tin: it takes an ecosystem (whole and undamaged) and forks it. Before this proposal, everyone who writes JS understands the words of the language to mean the same thing. Afterwards that will never be possible again. |
To the extent that the ecosystem is forked it is the ecosystem of type checkers that is forked, but that neither falls under the purview of TC39 nor is it at all fixed by this proposal. It is not any comfort to me that everyone should use the same characters of syntax if they don't agree on what they mean. |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as abuse.
This comment was marked as abuse.
This comment was marked as off-topic.
This comment was marked as off-topic.
The ironic thing is, actual type checking is again outsourced outside TC39 to type checkers that can all have their own implementation. So, essentially, the problem is only moved somewhere else but not actually dealt with inside JavaScript itself. |
Please be mindful of our Code of Conduct 🙏 |
@dfabulich if users want to simply[1] use typescript out of the box they should use bun or deno. this repo is a core ecmascript proposal and thus should be going its own path from first principles without necessarily worrying about the impact on prior art. the unforking comes after when prior art updates their code to use the new standard. |
I am (and have been) working on a counterproposal which could solve the underlying problems. I am proposing a system of arbitrary syntax transformation -- a macro system for JS, if you will. I believe such a solution could have some benefits:
|
I am personally think that runtime type checking is impossible due to rich type system in TypeScript. For example take a look on type-fest library which has super complex utility types like this one. If there will be type checker in JS engine then it will have to evaluate and check everything. Just take a look on how long it takes for TypeScript to check types in big projects and pretty much the same time browser will spend to do the same, of course it will be faster due to native environment, but still it will slow down page speed. Another question is what to do if the types are incorrect (and maybe the code will work in runtime), should browser through an error and break the page, if not then what will be the point of real type checking? I think maximum what is possible is some kind of type reflection, or adding the type text to decorators metadata to allow you to parse and use it in runtime (i.e. in schema validation like class-validator does) |
I have read through the arguments about why adding runtime type checks is impossible, and I am forced to say that I concur with them. Typescript already has a relatively advanced system which allows it to condition or refine its type understandings based on the results of runtime checks. That is already a powerful enough tool to be able to design an ideal system in which untrusted values are checked at the boundaries and internal static analysis can then be more or less "sound" in the type-theoretic sense. Because Typescript has such a system its system of type is able to have well-defined meaning, even in the absence of a compiler which emits any (non-explicit) runtime type checks. It seems likely that similar mechanism would prove useful to many extenders, allowing them to marry their theory to Javascript's actual (runtime) type system, thus providing the means for consensus to be reached on which constructions are "correct" in their language. |
Most of us have probably seen what kinds of monstrosities TypeScript is capable of committing when devs go wild and define acid trip like types, which extend themselves to infinity and beyond, resulting in more code for the types than for the actual code, it will result in JavaScript. No wonder why there are sometimes separate |
As I've said in my earlier comment referencing Python, it brings the same value to JS that Python's type annotations bring to Python. Specifically:
(2 and 3, of course, apply to many possible solutions, including current TypeScript. 1 is the big difference from current practices. But it's important to keep 2 and 3 in mind, when weighing against proposals like runtime type checking.) I apologize for apparently overexplaining earlier, but any assertion that this sort of system wouldn't be useful for JS needs to directly grapple with the usefulness of the same system in Python. If you have an argument against it, why does that argument not apply to Python's type annotations? |
I too want a solution that hits points 1, 2, and 3! As you mention the existing system hits points 2 and 3, but not 1. This proposal satisfies 1 and 3, but not 2. |
The difference with Python's system, now that I have a chance to sit down and look more carefully and look at Python's system, is that while Python allows multiple checkers it also defines the meaning of each of its typing syntaxes. While a given checker is not specified, there is ample documentation in the base language on what the various typing syntaxes (like generics) mean and how you should write types for each kind of code. To me that is very different than how JS would be able to write the same docs, which is to say it wouldn't. |
Since Python keeps getting mentioned, I think it's worth noting that, while Python doesn't assert type annotations at runtime ( from typing import get_type_hints
class Foo:
bar: str = "bar"
def __init__(self, baz: bool):
pass
get_type_hints(Foo) # {'bar': <class 'str'>}
get_type_hints(Foo.__init__) # {'baz': <class 'bool'>} This allows users to use those type annotations at runtime. For example, to perform runtime type checking with the I think that forced runtime type checking has been discussed plenty, in this issue and others. But it might be worth discussing if types should really be completely ignored, or if they should/could somehow be available at runtime. |
real talk, half the time in Solidjs you are fighting types |
According to the description of this proposal,
I think it would be better if type checking were done at runtime. To be clear, I suggest that the type checking should be done when running the actual code similar to what is done in PHP, not when parsing it similar to what is done in TypeScript. So for example I suggest that this:
should do roughly the same thing as this:
You mention in your FAQ that
While this is true for transpilation, if type checking isn't done at runtime as you suggest, the code will still have to be run through static type checkers. If type checking were done at runtime, however, it would allow to run the code directly in the browser in a type safe way without using any third-party tools to analyze it at all.
Is there any reason why you decided not to do this?
The text was updated successfully, but these errors were encountered: