-
Notifications
You must be signed in to change notification settings - Fork 229
Using typescript babel to transition from flow #1
Comments
TLDR:
This is a good question; I think that one of the challenges you may face is that type annotations are not considered valid in Additionally, when trying to import from So for example, if you have the following layout once you've compiled everything:
If // Note: this file cannot have any imports or exports; it needs to be globally scoped
declare module "a";
declare module "c";
declare module "c/lib/*"; One more thing is that for a given compilation, Babel can't have both TypeScript and Flow plugins loaded at the same time, so you'll need to remove the Flow plugin for a given project's compilation. |
This helps give me an idea of how I should start this off, thank you so much for taking the time to write it. I'm guessing the hardest part of this is assessing how long this refactor will take and any other costs. Right now I'm still a bit scared of the investment, it helps me plan for doing it after a couple more releases of our apps+packages though. |
Thanks for answering this. |
@richard-lopes Nope, not at this time. We've tried to avoid confusing users with syntax that won't actually work at runtime. |
To play the devil's advocate, as an alternative to using Flow or switching to TypeScript, you can get TypeScript type safety for JavaScript. TypeScript Types for JavaScriptYou can keep your files as Javascript and use TypeScript for checking types if you're using VSCode: Type Checking JavaScript. Doing this provides many of the famous benefits of TypeScript, such as intellisense: code completion, Go to Definition, Peek Definition, Find All References, Rename Symbol (across files), Change All Occurences, hover type reveal, etc. You can read more about TypeScript intellisense through JSDoc on the VSCode site. VSCode does not support every feature of JSDoc. You can check out their documentation of the features they do support for intellisense. SetupOpen user settings and add: "javascript.implicitProjectConfig.checkJs": true This tells VSCode to use TypeScript to type check the JavaScript files. Now in this the trick is to use JSDoc comments to document your types. When the TypeScript language service sees JSDoc comments, it uses those to understand the JavaScript's type system. You can define a type using /**
* @type {string} name
*/
function announce(name) {
alert(`Hello, ${name}!`)
} You can define a custom type using /**
* @typedef {Object<string, any>} Props
* @type {Props} props
*/
function Title(props) {
return (
<h1>{props.message}</h1>
)
} You can also define generics using the /**
* @param {T} t
* @template T
*/
const Bar = function (t) { return};
var bar = new Bar("hello"); // bar is a Bar<string> You can also import type definitions from other files: /**
* @typedef {import('../vnode').VNode} VNode
* @param {VNode} vnode
*/
function createNodeFromVnode(vnode) {
// Do stuff here...
} You can also do type casting, but it is more verbose. Say you have an element of type Node but you want to add an attribute to it. // btn will be type Node:
const btn = document.createElement('button')
// Make btn disabled.
// Since it's type Node, we need to cast it to type Element:
/** @type {Element} */(btn).setAttribute('disabled') Nice thing about JSDoc comments, including the verbose type casting, when you minify all of it goes away, leaving you with just JavaScript. Type Checking at Build TimeYou can add TypeScript type checking for your JavaScript as part of your build process with an NPM script: "checkjs": "tsc --allowJs --checkJs --noEmit --target ES6 lib/*.js" D.TS FilesIf you look at the default JSDoc Comments are Standard JavaSciptUnlike TypeScript, which needs to be compiled, or Flow, which needs to be stripped out at build time, JSDoc comments are standard JavaScript comments. This means that the type information they provide stays in the source code and can also be in the development version of the code before minification. Minification with Uglify will automatically strip out the JSDoc comments, including any extra markup for type casting. Although proponents of TypeScript and Flow are fond of saying they are just JavaScript, you can run them in the browser as is. JavaScript with JSDoc types can. Expando PropertiesBecause TypeScript is a static type checker that only checks during code time and build time, it can't handle expando properties. Instead it will flag these as not existing on the object. When using JSDoc for types, because TypeScript is running under the hood, you'll run into the same problem. Although using expando properties is a normal thing in JavaScript, to use them with TypeScript you need to escape them with braces and quotes. The following code is valid JavaScript: const btn = document.createElement('button');
// Add custom property
btn.mounted = true;
document.body.appendChild(btn) With TypeScript type checking, const btn = document.createElement('button');
// Add custom property
btn['mounted'] = true;
document.body.appendChild(btn) JSDoc vs TypeScriptWhich is better? If you want the very best support for types, go with TypeScript. If you just want to be able to write JavaScript and use Babel stage 0 and stage 1 now, but you want enhanced intellisense and type safety, use JSDoc. If your team consists of geeking JavaScript nerds who are hesitant about introducting types, go with JSDoc. If your team have previously worked with C++, C# or Java, they're going to love TypeScript. TypeScript features may not always match Babel features. Take for example how TypeScript implements private members in a class with the |
What would be the recommended practice for switching from flow to typescript?
We (nteract) have a large code base (as a lerna monorepo) written with flow and this seems like a good way for us to transition individual packages to typescript, since everything is currently babel backed in our code base.
The text was updated successfully, but these errors were encountered: