上下文
纱线workspaces提供了一种方便的方式来依赖单仓库中的软件包。当程序包A依赖程序包B时,程序包B中定义的接口等将在程序包A中得到适当解析。
问题
我遇到一个问题,如果程序包B依赖于外部库,但是该外部库缺少类型,因此程序包B已创建了自己的some-library.d.ts
文件。当使用tslint
对程序包A进行工作时,此自定义定义文件将针对程序包B中的表达式正确解析,但对于与程序包B中的类型兼容的程序包A中的表达式则无法正确解析。
我在这里推送了此问题的简化示例:
https://github.com/tommedema/tslint-yarn-workspaces
其核心如下。
packages / a / src / index.ts
// tslint:disable:no-console
import { someDependedFn } from 'b'
export const someDependingFn = (): void => {
const someNr = someDependedFn('pascal-case-me')
console.log(someNr)
}
packages / b / src / index.ts
import camelCase from 'camelcase'
export const someDependedFn = (str: string): string => {
const camelStr = camelCase(str, { pascalCase: true })
return camelStr
}
packages / b / src / typings / camelcase / index.d.ts
// Type definitions for camelcase 5.0
// Project: https://github.com/sindresorhus/camelcase
// tslint:disable only-arrow-functions completed-docs
declare module 'camelcase' {
export default function camelCase(
strs: string | string[],
options: {
pascalCase?: boolean
}
): string
}
现在,如果您将目录更改为软件包a
并运行yarn build
,则可以正常工作。但是,如果您运行yarn lint
,它将抛出:
$ tslint -p tsconfig.json
ERROR: packages/b/src/index.ts[4, 20]: Unsafe use of expression of type 'any'.
ERROR: packages/b/src/index.ts[6, 10]: Unsafe use of expression of type 'any'.
TSLint无法识别程序包B所依赖的类型,但仅在从程序包A运行tslint时才抱怨(不期望)。在软件包B中,tslint不会抱怨(如预期)。
问题
我当然可以在软件包A中手动添加camelcase
的类型,但这似乎明显违反了关注点分离:软件包A不应该知道软件包B依赖于驼峰包或X。或Y。仅应了解程序包B的公共API,即dependedFn
。
在使用yarn工作区时,如何设置tslint使其正确解析这些间接输入定义?
答案 0 :(得分:0)
您可以通过从tsconfig.json
中删除这些行来使TSLint发挥作用:
"baseUrl": "./packages",
"paths": {
"*": ["./*/src"]
},
这些行告诉TypeScript编译器和TSLint,在导入模块时,它们不应将模块a
和b
视为包,而应使用baseUrl
和paths
个参数,然后编译单个TypeScript文件。 TypeScript文档的“模块分辨率->路径映射”部分中记录了此行为:
https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
相反,如果我理解正确,您想将a
和b
视为独立的软件包。为此,您应该删除路径映射,然后TypeScript和TSLint将它们视为npm软件包。
更新(基于评论中的讨论)
在您的项目中,使用以下命令运行TSLint:
tslint -p tsconfig.json
但是您使用以下命令运行TSC:
tsc src/index.ts --outDir dist
您的TSLint根据tsconfig.json
中的规则使用TypeScript编译器API进行检查。但是您的TypeScript编译器不使用tsconfig.json
规则。在实际项目中,两个命令都将使用tsconfig.json
当您也开始使用tsconfig.json
进行编译时,与使用TSLint一样,在解决2度依赖关系类型时也会遇到相同的问题:
$ tsc -p tsconfig.json
../b/src/index.ts:1:23 - error TS7016: Could not find a declaration file for module 'camelcase'. '/home/victor/work/tslint-yarn-workspaces.org/node_modules/camelcase/index.js' implicitly has an 'any' type.
Try `npm install @types/camelcase` if it exists or add a new declaration (.d.ts) file containing `declare module 'camelcase';`
1 import camelCase from 'camelcase'
~~~~~~~~~~~
之所以会发生这种情况,是因为根据设计脚本,路径映射的模块导入的编译方式有所不同,然后从node_modules
正常导入
https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
按照答案第一部分的说明。
我建议您在项目中使用常规导入,以免出现工具方面的麻烦:
"watch": "lerna run --parallel -- watch"
中拥有package.json
脚本"watch": "tsc -p tsconfig.json -w"
。npm run watch
在每个程序包中以监视模式启动TypeScript编译器。