4 ms·
> Given that TypeScript is a transpiler along with a static type-checker, it's not always easy to tell which features are going to have build-time vs run-time e
by lewisl9029 9y ago
> Given that TypeScript is a transpiler along with a static type-checker, it's not always easy to tell which features are going to have build-time vs run-time effects (e.g. private properties, property decorators)
This is a huge part of why I tend to prefer Flow for my projects these days as well.
I really value the fact that Flow is just a thin layer of static type annotations you place on top of your spec-compliant JavaScript, and none of its features have any chance of introducing unexpected runtime behavior.
Also, I'd like to add that using Flow with Babel transpilation targeting a ES20xx preset largely guarantees that the source code you're writing is valid spec-compliant JavaScript that can run without transpilation one day (requiring only a dead-simple type-stripping transform using something like https://www.npmjs.com/package/babel-plugin-transform-flow-strip-types https://www.npmjs.com/package/babel-plugin-transform-flow-st... or https://github.com/flowtype/flow-remove-types https://github.com/flowtype/flow-remove-types), and I've had great success with simply dropping all/parts of the transpilation step as the features I use start to become supported in node/browsers/react-native/electron/runtime-polyfills/etc for apps where I don't plan on supporting browsers more than a few versions behind latest, which has been an absolute godsend for debugging in both development and production.
I highly encourage people to try it out on a project where they can afford to do the same (i.e. for packaged projects where you have control over the runtime environment like Electron or React Native, or for web projects where most of your users happen to be also web developers). It's really been a breath of fresh air after dealing with all sorts of subtle transpilation induced bugs/edge-cases.
To be clear, I'm not trying to bash TypeScript, because it's an awesome project, with top-class tooling that has attracted an amazing community around it. I just wanted to remind all the people mindlessly shouting "TypeScript has won" into their own silos, that Flow is also a great type system, that just happens to be designed with a fundamentally different set of trade-offs in mind. That alone doesn't make either system better or worse than the other, but it does mean there are use cases where Flow can excel over TypeScript and vice versa, and that you should carefully consider your project's needs and what characteristics you value in a type system before simply cargo-culting one or the other.
- esamatti 9y agoThis is possible with Typescript too with Babel 7. See my comment here https://news.ycombinator.com/item?id=15236089 https://news.ycombinator.com/item?id=15236089
- lewisl9029 9y agoThanks for bringing that to my attention! That sounds super exciting. I'm definitely going to have to give that a shot once it's ready. Flow's excellent React Native support has also been a large part of why I've mostly been working in Flow-land these days, so I'm glad to hear TypeScript will soon become a first-class citizen in that ecosystem as well. EDIT: As a follow up question, please correct me if I'm misunderstanding anything, but from what I've gathered so far, I suspect that the new babel-preset-typescript can't quite do _just_ type-stripping can it? Since some features in TypeScript have runtime implications, those would still have to be transformed as opposed to simply stripped, correct? So it looks like that fundamental difference between TypeScript and Flow remains in tact, but it's certainly still a huge leap in usability to be able to adopt the Babel toolchain as a first-class way of building TypeScript projects. Huge props to the Babel and TypeScript teams for making that possible!
- esamatti 9y ago> I suspect that the new babel-preset-typescript can't quite do _just_ type-stripping can it? Since some features in TypeScript have runtime implications, those would still have to be transformed as opposed to simply stripped, correct? I'm quite new to Typescript myself so I really don't know. At least I'm not aware of such features and don't think this Babel feature would make much sense if there were any? EDIT: I think some of the runtime features are just TS doing ES6 to ES5 compiling. Such as "for of" loops, generators etc., but since those are just ES6 syntax they can be handled by other Babel plugins/presets or even by modern browsers directly.
- lewisl9029 9y agoThe two most obvious examples I can think of off the top of my head are features like Enums and constructor param visibility settings. Both must be transformed to retain their runtime properties, and both don't exist in any ratified ES spec. Luckily enough they both also happen to have fairly straightforward mappings to their respective JS implementations, and once you know that they do introduce runtime behavior (and it's fairly easy to notice that they do), you can simply avoid them, so the practical impact of these more obvious cases can be limited. More troubling cases do exist though. I vaguely remember once coming across some obscure runtime behavior for decorators where they attach runtime metadata that's supposedly used for type reflection, which is a runtime effect that's definitely not immediately obvious or intuitive. This and other potential obscure edge cases like it, some of which may exist in TypeScript today and some of which might be introduced in some future version, are part of what makes Flow's focus on providing trivially removable static typings on top of spec-compliant JavaScript so attractive to me (in addition to opening up the option of minimizing the surface area of your transpilation step or skipping transpilation altogether).
- wildpeaks 9y agoTo be fair, one can also stick to .js files and use TS in checkJs mode, in which case it uses jsDoc comments to add types information, so there is no extra step to strip types. The downside is that a few features don't have a jsDoc equivalent. But it would already catch most of the things you'd use a type checker for, without the hassle of going full Typescript: you could even completely remove typescript from the project and it would still work given they're just JS comments.
- lewisl9029 9y agoRight, that's a great point. If the set of features that aren't supported in the jsDoc equivalent are the same set of features that end up requiring runtime transforms, then I can picture this to be an excellent way to use TypeScript the same way I do with Flow (which also supports a comment-mode syntax, but it doesn't have as compelling a use case in Flow since the standard syntax doesn't require any transformations to begin with).