免责声明:一般来说,我仍然是一些新的Flow和静态类型,所以我很可能会忽略这个问题容易/明显的东西.
假设我有一个名为的库my-library
.该库向其用户公开单个模块,该模块index.js
导入一些其他模块(moduleA.js
和moduleB.js
)供内部使用.
我希望将Flow与此库一起使用,既可用于内部开发,也可用于index.js.flow
具有模块声明的文件,该模块声明适用于同时使用Flow的库用户.所以文件结构看起来像这样:
- index.js
- index.js.flow (contains the module declaration for library users)
- moduleA.js
- moduleA.js.flow (just exported type definitions, no module declaration)
- moduleB.js
- moduleB.js.flow (just exported type definitions, no module declaration)
Run Code Online (Sandbox Code Playgroud)
问题是index.js.flow
模块声明需要使用来自moduleA.js.flow
和的类型moduleB.js.flow
.(我原因moduleA.js.flow
而moduleB.js.flow
不是直接在.js文件中定义类型的原因是.js文件中的类型定义将被Babel剥离,我希望它们仍然存在于库用户的某个地方).
我知道以下内容不会与导入的外部JS进行类型检查my-module
:
index.js.flow(这不起作用)
import type { SomeType } from './moduleA'
declare module 'my-module' {
declare function exports(): {
someMethod: () => SomeType
}
}
Run Code Online (Sandbox Code Playgroud)
在导入时,SomeType似乎在模块声明中不可用,但在本地定义它确实有效:
index.js.flow(这个有效)
export type SomeType = string
declare module 'my-module' {
declare function exports(): {
someMethod: () => SomeType
}
}
Run Code Online (Sandbox Code Playgroud)
所以,一个解决方法就是定义,并从内部导出所有类型的index.js.flow
,只是有moduleA.js
和moduleB.js
导入(不包括.js.flow
文件moduleA
和moduleB
),但似乎怪异都在根流文件类型定义,而不是在.js.flow
文件匹配这些类型源自的模块.
或者,我知道我可以在各自的模块中定义开发类型,并在index.js.flow
模块声明中再次定义它们,但如果可能的话,我不希望在两个不同的地方重复类型定义.
我非常感谢任何帮助,找出如何最好地组织这个.(再一次,我知道我有一个非常可靠的机会,我正在做一些愚蠢的事情或忽视一些显而易见的事情.)
.js.flow
文件的目的与您的实现中的相应文件完全相同.js
,只是它们不是由Babel翻译的.特别是,它们像对应的.js
文件一样导入和导出东西.此外,就像.js
文件根据模块驻留在文件系统中的位置自动与模块关联一样,文件也是如此.js.flow
.
按照问题中的示例,假设index.js
's module.exports
是一个函数,它返回一个包含someMethod
类型属性的对象() => SomeType
,其中类型SomeType
是由其导出的moduleA.js
.然后我们可以在以下方面index.js.flow
:
// @flow
import type { SomeType } from './moduleA'
declare module.exports: () => {
someMethod: () => SomeType;
};
Run Code Online (Sandbox Code Playgroud)
以下内容moduleA.js.flow
:
// @flow
export type SomeType = string;
Run Code Online (Sandbox Code Playgroud)
假设我们把index.js.flow
和moduleA.js.flow
中src/node_modules/my-module/
,我们可以测试我们的设置是由具有下列正确test.js
的src/
:
// @flow
var foo = require('my-module');
(foo().someMethod(): number); // error (string incompatible with number)
Run Code Online (Sandbox Code Playgroud)