如何避免在模块声明中重复类型定义?

Sha*_*ere 5 flowtype

免责声明:一般来说,我仍然是一些新的Flow和静态类型,所以我很可能会忽略这个问题容易/明显的东西.

假设我有一个名为的库my-library.该库向其用户公开单个模块,该模块index.js导入一些其他模块(moduleA.jsmoduleB.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.flowmoduleB.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.jsmoduleB.js导入(不包括.js.flow文件moduleAmoduleB),但似乎怪异都在根流文件类型定义,而不是在.js.flow文件匹配这些类型源自的模块.

或者,我知道我可以在各自的模块中定义开发类型,并在index.js.flow模块声明中再次定义它们,但如果可能的话,我不希望在两个不同的地方重复类型定义.

我非常感谢任何帮助,找出如何最好地组织这个.(再一次,我知道我有一个非常可靠的机会,我正在做一些愚蠢的事情或忽视一些显而易见的事情.)

Avi*_*uri 7

.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.flowmoduleA.js.flowsrc/node_modules/my-module/,我们可以测试我们的设置是由具有下列正确test.jssrc/:

// @flow

var foo = require('my-module');

(foo().someMethod(): number); // error (string incompatible with number)
Run Code Online (Sandbox Code Playgroud)

  • 可以这样想:`.js.flow`只是替换`.js`以进行类型检查.什么会`声明模块`意味着在常规`.js`文件中?那个文件已经*定义了一个模块.在这个例子中,`index.js`已经因为位于`node_modules/my-module`而定义了模块`my-module`.这与*.js.flow`的情况完全相同*.在常规`.js`或`.js.flow`文件中使用`declare module`应该是一个错误(它当前不是,但这是一个错误).它的使用应限于你的`.flowconfig`中指向的"全局"声明. (2认同)