如何键入不具有Flow的NPM包的模块?

时间:2018-04-06 19:22:16

标签: flowtype

免责声明我是Flow的新手,对文档非常困惑,所以我可能会遗漏一些明显的内容。

我有一个模块如下:

// ./src/lib/myModule/MyModule.js
// @flow
class MyModule {
  constructor(str) {
    this.aString = str
  }
}
export { MyModule as AnotherName }

我以这种方式导出模块,因此我可以导入./myModule并仍然将MyModule拆分为多个文件,如果我需要:

// ./src/lib/myModule/index.js
export * from './MyModule'

我还有一个类型文件:

// ./src/lib/myModule/MyModule.types.js
// @flow
declare module 'MyModule' {
  declare class MyModule {
    sString: string;
    constructor(str: string);
  }
}

然后我使用模块:

// ./src/index.js
// @flow
import { MyModule } from './src/lib/myModule';

const myModule = new MyModule('foo')

这是整个目录布局:

src/
├── index.js
└── lib
    └── myModule
        ├── index.js
        ├── MyModule.js
        └── MyModule.types.js

这是我的.flowconfig

[ignore]
<PROJECT_ROOT>/build/*
<PROJECT_ROOT>/coverage/*

[include]

[libs]
<PROJECT_ROOT>/src/**/*.types.js

[lints]
sketchy-null=error
untyped-type-import=warn
untyped-import=warn
unclear-type=error
unsafe-getters-setters=warn

[options]
suppress_comment= \\(.\\|\n\\)*\\$FlowIgnore

[strict]

[version]
^0.69.0

如何让Flow了解src/lib/myModule/MyModule.types.js中的声明与src/lib/myModule/MyModule.js有关?我找不到一种语法来告诉流,ES模块文件和类型文件中的类MyModule是相同的。

1 个答案:

答案 0 :(得分:0)

MyModule.types.js需要命名为MyModule.js.flow。导入文件时,流将自动从具有相同名称的.js.flow文件中提取类型信息(如果存在)。您是正确的,流文档中目前缺少此信息:https://github.com/facebook/flow/issues/3609

MyModules.js.flow的内容应为

// @flow

declare export class AnotherName {
  sString: string;
  constructor(str: string): AnotherName;
}

你所拥有的一些变化:

  • 您无需在此声明模块。 Flow了解.js.flow文件仅适用于此文件,因此我们不会声明全局。
  • 需要声明构造函数的返回类型(AnotherName)。
  • 将导出声明为AnotherName而不是MyModule,因为导入此类的文件请参阅AnotherName;模块内部使用的名称与文件的类型检查用法无关。

现在,使用此文件时,

// @flow

import { AnotherName } from './MyModule';

// Good
const anotherName1 = new AnotherName('123');
// Flow Error
const anotherName2 = new AnotherName(123);

请注意,如果您从index.js中重新导出AnotherName,并且在使用它时始终从index.js导入AnotherName,则需要使用index.js。流文件以及类型检查的任何好处。或者你可以在index.js的顶部添加// @flow pragma。