2016-07-22 9 views
10

以下絞り込まれたコードで呼び出すことができない。奇妙 `メソッドはnullの可能性/未定義の[値]

// @flow 
'use strict'; 

import assert from 'assert'; 

class Node<V, E> { 
    value: V; 
    children: ?Map<E, Node<V,E>>; 

    constructor(value: V) { 
     this.value = value; 
     this.children = null; 
    } 
} 


function accessChildren(tree: Node<number, string>): void { 

    if (tree.children!=null) { 
     assert(true); // if you comment this line Flow is ok 
     tree.children.forEach((v,k)=>{}); 
    } else { 
    } 

} 

&hellip。ラインの読み場合

$ npm run flow 

> [email protected] flow /home/blah/blah/blah 
> flow; test $? -eq 0 -o $? -eq 2 

es6/foo.js:21 
21:    tree.children.forEach((v,k)=>{}); 
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `forEach`. Method cannot be called on possibly null value 
21:    tree.children.forEach((v,k)=>{}); 
^^^^^^^^^^^^^ null 

es6/foo.js:21 
21:    tree.children.forEach((v,k)=>{}); 
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `forEach`. Method cannot be called on possibly undefined value 
21:    tree.children.forEach((v,k)=>{}); 
^^^^^^^^^^^^^ undefined 


Found 2 errors 

::次のメッセージをチェックするフロータイプを失敗しassert(true)がコメントアウトされ、フローは満足です!

何がありますか?

PS:

.flowconfig

$ cat .flowconfig 
[options] 
esproposal.class_static_fields=enable 

.babelrc

$ cat .babelrc 
{ 
"presets": ["es2015"], 
"plugins": ["transform-object-rest-spread", "transform-flow-strip-types", "transform-class-properties"] 
} 

package.json

:誰もが私の.flowconfig.babelrcpackage.jsonファイルが目立たあり、不思議場合
$ cat package.json 
{ 
"name": "simple-babel-serverside-node-only-archetype", 
"version": "1.0.0", 
"description": "", 
"main": [ 
"index.js" 
], 
"scripts": { 
"build": "babel es6 --out-dir es5 --source-maps", 
"build-watch": "babel es6 --out-dir es5 --source-maps --watch", 
"start": "node es5/index.js", 
"flow": "flow; test $? -eq 0 -o $? -eq 2" 
}, 
"author": "", 
"license": "ISC", 
"devDependencies": { 
"babel-cli": "^6.6.5", 
"babel-core": "^6.7.4", 
"babel-plugin-transform-class-properties": "^6.10.2", 
"babel-plugin-transform-flow-strip-types": "^6.8.0", 
"babel-polyfill": "^6.7.4", 
"babel-preset-es2015": "^6.9.0", 
"babel-runtime": "^6.6.1", 
"flow-bin": "^0.27.0" 
}, 
"dependencies": { 
"babel-plugin-transform-object-rest-spread": "^6.8.0", 
"babel-polyfill": "^6.7.4", 
"source-map-support": "^0.4.0" 
} 
} 
+0

これは、http://stackoverflow.com/questions/38479426/dynamic-type-tests-not-working-as-expectedと全く同じです。 – vkurchatkin

+0

@vkurchatkin当初私はそれほど多くはないと思っていましたが、そうではありません。 'assert(true)'は 'tree.children'を変更する方法がないので、Flowはそれを許していなければなりません。これは、あなたが 'this'にアクセスする可能性のあるメンバーメソッドが呼び出された場所にリンクする投稿とは異なります。 Flowがおそらく 'assert'関数が' tree'ローカル変数上のクロージャを捕捉できるように作成されたとFlowが考慮しない限り、私はうっかりしません。 –

答えて

4

あなたの場合はhereと記載されています。

フローがわからない、そのasserttreeを変更しません。 コードに次の行を追加して実行します。呼び出されるとassert関数はtree.childrenからnullに設定されるため、実行時エラーが発生します。

const root = new Node(1); 
const child = new Node(2); 

root.children = new Map([['child', child]]); 

assert =() => root.children = null; 

accessChildren(root); 

はい、かなり奇妙なコードですが、Flowはわかりませんが、あなたはそれを書きません。

+0

明快で簡潔な回答に感謝します。実際には意味があります! –

4

他は正しい説明を指摘しています。幸いなことに、この作品:

// @flow 
'use strict'; 

import assert from 'assert'; 

class Node<V, E> { 
    value: V; 
    children: ?Map<E, Node<V,E>>; 

    constructor(value: V) { 
    this.value = value; 
    this.children = null; 
    } 
} 


function accessChildren(tree: Node<number, string>): void { 

    const children = tree.children; // save possibly mutable reference to local 
    if (children!=null) { 
    assert(true); // if you comment this line Flow is ok 
    children.forEach((v,k)=>{}); 
    } else { 
    } 

} 

はまた、将来のフローのプロパティのみを読んだことがあるだろう、とクラスの読み取り専用のプロパティとしてchildrenを宣言することで、フローは、元のコードをチェックタイプを維持することができるはずです。

関連する問題