flow(1)のコマンドラインオプションを眺めていたら、 suggest というサブコマンドがありました*1。
これは、JavaScriptファイルを引数にとって、そのスクリプトにflowtype annotationを付けるパッチを生成するコマンドのようです。
たとえばこういうスクリプトに対して:
function add(a, b) {
return a + b;
}
console.log(add(1, 2)));
次のようなパッチを生成しました:
--- old
+++ new
@@ -1,4 +1,4 @@
-function add(a, b) {
+function add(a: number, b: number) : number{
return a + b;
}
これは結構すごいんじゃないでしょうか。
Reactの1ファイルにも試してみました。
flow suggest src/isomorphic/modern/class/ReactComponent.js
で以下のような出力です。
--- old
+++ new
@@ -13,7 +13,7 @@
var ReactNoopUpdateQueue = require('ReactNoopUpdateQueue');
-var canDefineProperty = require('canDefineProperty');
+var canDefineProperty: boolean = require('canDefineProperty');
var emptyObject = require('emptyObject');
var invariant = require('invariant');
var warning = require('warning');
@@ -21,7 +21,7 @@
/**
* Base class helpers for the updating state of a component.
*/
-function ReactComponent(props, context, updater) {
+function ReactComponent(props, context, updater) : void{
this.props = props;
this.context = context;
this.refs = emptyObject;
@@ -57,7 +57,7 @@
* @final
* @protected
*/
-ReactComponent.prototype.setState = function(partialState, callback) {
+ReactComponent.prototype.setState = function(partialState, callback) : void{
invariant(
typeof partialState === 'object' ||
typeof partialState === 'function' ||
@@ -85,7 +85,7 @@
* @final
* @protected
*/
-ReactComponent.prototype.forceUpdate = function(callback) {
+ReactComponent.prototype.forceUpdate = function(callback) : void{
this.updater.enqueueForceUpdate(this);
if (callback) {
this.updater.enqueueCallback(this, callback, 'forceUpdate');
@@ -98,7 +98,7 @@
* modern base class. Instead, we define a getter that warns if it's accessed.
*/
if (__DEV__) {
- var deprecatedAPIs = {
+ var deprecatedAPIs: {isMounted: [string, string], replaceState: [string, string]} = {
isMounted: [
'isMounted',
'Instead, make sure to clean up subscriptions and pending requests in ' +
@@ -110,10 +110,10 @@
'https://github.com/facebook/react/issues/3236).',
],
};
- var defineDeprecationWarning = function(methodName, info) {
+ var defineDeprecationWarning = function(methodName: string, info) : void{
if (canDefineProperty) {
Object.defineProperty(ReactComponent.prototype, methodName, {
- get: function() {
+ get: function() : void{
warning(
false,
'%s(...) is deprecated in plain JavaScript React classes. %s',
@@ -125,7 +125,7 @@
});
}
};
- for (var fnName in deprecatedAPIs) {
+ for (var fnName: string in deprecatedAPIs) {
if (deprecatedAPIs.hasOwnProperty(fnName)) {
defineDeprecationWarning(fnName, deprecatedAPIs[fnName]);
}
推論しきれてない部分もありますが、けっこうできているなという印象です。逆にいえば、これで補完されない部分は推論できないということなので、そういうところだけ人が書けばいいということですね。