5 ms·
Runtime type information is against the goals of TypeScript. https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals https://github.com/Microsoft/
by __ryan__ 3y ago
Runtime type information is against the goals of TypeScript.
https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals https://github.com/Microsoft/TypeScript/wiki/TypeScript-Desi...
Edit:
Non-goals:
…
5. Add or rely on run-time type information in programs, or emit different code based on the results of the type system. Instead, encourage programming patterns that do not require run-time metadata.
- danielheath 3y agoDid the comment you're replying to get edited? They are pretty explicitly talking about statically known type information, not runtime.
- __ryan__ 3y agoThey’re suggesting outputting runtime type information by emitting different code based on the type of the value passed to their hypothetical “Type.keys()” function.
- danielheath 3y agoAhh, that makes sense then; thanks for clarifying.
- tentacleuno 3y agoWell that's interesting. That means decorator metadata was a non-goal, despite being supported for ages.
- IggleSniggle 3y agoThe Reflect.defineMetadata API and the long-supported decorators syntax come from very early versions of Typescript when Typescript was (maybe) more actively trying to steer the direction of ECMAScript by implementing features that were Stage 2 proposals. Typescript only got official ECMAScript decorator support in the recent v5. ECMAScript decorators only got to stage 3 in April ‘22. But decorator syntax is just a kind of syntax sugar over passing a function through another function, and you can do that today to achieve runtime type information (see zod etc). Zod could be rewritten using decorator syntax and still be “just JavaScript” while providing compile-time type support. The distinction being that supporting ECMAScript features is a goal for Typescript, but they were perhaps too aggressive early on in investing in decorators and the Reflect Metadata API. They had the wisdom to put these behind “experimental” flags, but I think they got quite popular within the typescript community due to the early adoption of both Typescript and both those features by Angular, which was really the only major lib using TS for quite some time.
- tentacleuno 3y ago> Typescript only got official ECMAScript decorator support in the recent v5. ECMAScript decorators only got to stage 3 in April ‘22. Yah, they've been out for ages. It's quite surprisingly how 1. long it's taken ECMA and 2. how quickly TypeScript took advantage of decorator syntax to improve TypeScript. I'd say it's a definite win for us people who love decorators. > But decorator syntax is just a kind of syntax sugar over passing a function through another function, and you can do that today to achieve runtime type information I'll have a look at Zod, thank you! I have to admit I like the simplicity of decorators; I'm playing with Dependency Injection and, while the loss of parameter injection is a bit disappointing, there are ways to work around it, e.g. @Injectable([Dependency]) class Service { constructor (private dependency: Dependency) { } } > [...] features by Angular, which was really the only major lib using TS for quite some time. Definitely. Although it'd be interesting to see how Angular handles the transition away from parameter injection; there's an open issue about it on their GitHub, but from what I can see none of the core members have spoken about it yet. <https://github.com/angular/angular/issues/50439 https://github.com/angular/angular/issues/50439> The main proposal from a community member is to replace them with the Service Locator pattern (ew). Thankfully someone in-thread provided them with a little wisdom regarding why that's a terrible idea. Here's hoping Angular keeps a nice API.
- hellcow 3y agoThis is my biggest issue with the language. Fetch returns “any” meaning you can’t trust the data you received is actually the data you expected. Bugs from this mismatch will be many lines away (on first use) and more difficult to find. Because of this “goal of the language” you cited, there’s no built-in way to validate any data at runtime. In nearly any other typed language I have some deserialization mechanism. Not so in Typescript! This decision led to more bugs in our codebase than any other. The compiler actively lies to you about the types you’ll have at runtime. The only solutions are codegen or writing validators to poorly approximate what Typescript should give us for free.
- madeofpalk 3y agoThe TS devs have mentioned that they wish JSON.parse returned unknown, but the change is too disruptive now.
- iainmerrick 3y agoIt would be a lot nicer if it instead returned some JsonType that’s a union of all the possible JSON values. Anyone know if there’s a good reason why it doesn’t do that?
- striking 3y agoYou can pass an arbitrary rehydration function, which can return non-JSON-representable types
- Dylan16807 3y agoIt could look at the return type of your reviver function, or at least whether you passed one in.
- kristiandupont 3y agoThere's a big discussion about this: https://github.com/microsoft/TypeScript/issues/1897 https://github.com/microsoft/TypeScript/issues/1897. The benefit seems extremely limited to me. Valid JSON is obviously a subset of `any`, but I can't think of a situation where that particular specificity provides any value. Can you?
- valenterry 3y agoInteresting, I think it indeed falls under "emit different code based on the results of the type system" even though - thank you for the link. I'm not sure if there is a) any "programming pattern" that can avoid this without other drawbacks and b) if there is any problem with emitting different code based on the types (at compiletime). I suppose it could lead to breaking behaviour if the typesystem is changed, since it now can impact runtime code. Personally, I think this would be more than worth it, but maybe the typescript team has a different opinion or other reason.
- heisenbit 3y agoThis is why Angular for dependency injection as well as some ORMs require non-standard Typescript emitted during compile time for a long time now. It looks a quite locked-up conflict.