[0] https://github.com/GoogleFeud/ts-runtime-checks
[1] https://github.com/moltar/typescript-runtime-type-benchmarks
opt-in makes sense if you want these checks in production. The appeal of a "check everything" debug mode is that you wouldn't have to modify your TS at all to use it.
>TypeScript does not modify this code when it compiles to JavaScript
TypeScript does not modify any code which is valid JavaScript. Your idea of adding some sort of "debug build" to TypeScript would never be performed by `tsc`, but perhaps by bundlers, etc.
You might want to look up libraries like zod, or even better, Effect: https://effect.website/
Effect is huge, and does seemingly everything, but it probably does the specific thing you want to do now, with the ability to extend to the other stuff as you need/want
It makes Typescript a descriptive, rather than expressive, language with weak semantics.
I'll nitpick with one complaint though...
const values = std.AutoHashMap(Point, u32);
defer values.deinit();
try values.put(Point{ .x = 0, .y = 0 }, 1);
// ~~~~~~^~~~ error: expected 3 argument(s), found 2
> The mistake here isn't on that line, and it doesn't have to do with the number of arguments. Rather, it's that I forgot to call .init() on the hash mapWell...
>>> class MyType():
... def test(self, a, b): return a + b;
...
>>> x = MyType
>>> x.test(1, 2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: test() missing 1 required positional argument: 'b'
How else do you want unbound functions to behave when you haven't constructed an instance of the type yet? (And FWIW, zls in vscode correctly annotates values as having type `type` for me)But before we even get to that stage, I would prefer that "." isn't the syntax for both types of call.
They're semantically similar, but not the same, which is actually exactly the place where you should distinguish syntax. Using parentheses for both expression grouping and function calls doesn't hurt readability much, but using them for both function calls and array access would. This falls more in the latter category.
For the first one, constructors should generally do required init, although there are circumstances where that's very hard. Hence the builder pattern.
Also, the type is different and ZLS will insert the hint if enabled.
There's an interesting point here, though: while comptime lets Zig unify function calls and generic type instantiation, this also creates the possibility of confusing the two and getting confusing error messages.
An implementation defined behaviour worse than C, that's surprising..
Ada has the same issue, I wonder if Ada users can tell us if this pitfall is an issue or not in practice.