Announcing Import Type
This post announced import types when it was introduced. For current syntax and behavior, see the Module Types documentation.
As of Flow 0.3.0, it's now possible to import types from another module. So, for example, if you're only importing a class for purposes of referencing it in a type annotation, you can now use the new import type syntax to do this.
Motivation
Has this ever happened to you:
// @flow
// Post-transformation lint error: Unused variable 'URI'
import URI from "URI";
// But if you delete the require you get a Flow error:
// identifier URI - Unknown global name
module.exports = function(x: URI): URI {
return x;
}
Now you have an out! To solve this problem (and with an eye toward a near future with ES6 module syntax), we've added the new import type syntax. With import type, you can convey what you really mean here — that you want to import the type of the class and not really the class itself.
Enter Import Type
So instead of the above code, you can now write this:
// @flow
import type URI from 'URI';
module.exports = function(x: URI): URI {
return x;
};
If you have a module that exports multiple classes (like, say, a Crayon and a Marker class), you can import the type for each of them together or separately like this:
// @flow
import type {Crayon, Marker} from 'WritingUtensils';
module.exports = function junkDrawer(x: Crayon, y: Marker): void {}
Transformations
Like type annotations and other Flow features, import type need to be transformed away before the code can be run. The transforms will be available in react-tools 0.13.0 when it is published soon, but for now they're available in 0.13.0-beta.2, which you can install with
npm install react-tools@0.13.0-beta.2
Anticipatory Q&A
Wait, but what happens at runtime after I've added an import type declaration?
Nothing! All import type declarations get stripped away just like other flow syntax.
Can I use import type to pull in type aliases from another module, too?
EDIT: Yes! As of Flow 0.10 you can use the export type MyType = ... ; syntax to compliment the import type syntax. Here's a trivial example:
// @flow
// MyTypes.js
export type UserID = number;
export type User = {
id: UserID,
firstName: string,
lastName: string
};
// @flow
// User.js
import type {UserID, User} from "MyTypes";
function getUserID(user: User): UserID {
return user.id;
}
Note that we only support the explicit named-export statements for now (i.e. export type UserID = number;). In a future version we can add support for latent named-export statements (i.e. type UserID = number; export {UserID};) and default type exports (i.e. export default type MyType = ... ;)...but for now these forms aren't yet supported for type exports.