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]); }
推論しきれてない部分もありますが、けっこうできているなという印象です。逆にいえば、これで補完されない部分は推論できないということなので、そういうところだけ人が書けばいいということですね。
*1:試したのはflow 0.35.0です