Tom*_*Tom 11 typescript tslint yarnpkg yarn-workspaces
上下文
纱线工作空间提供了一种依赖单声道包装的便捷方式.当包A依赖于包B时,包B中定义的接口等在包A中被适当地解析.
问题
我面临的问题是,如果包B依赖于外部库,但外部库缺少打字,因此包B创建了自己的some-library.d.ts
文件.当使用tslint
lint包A时,对于包B中的表达式,此自定义定义文件已正确解析,但对于包A中与包B中的类型一起使用的表达式则无法解析.
我在这里推出了一个简单的例子:
https://github.com/tommedema/tslint-yarn-workspaces
它的核心如下.
包/ 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)
}
Run Code Online (Sandbox Code Playgroud)
包/ B/src目录/ index.ts
import camelCase from 'camelcase'
export const someDependedFn = (str: string): string => {
const camelStr = camelCase(str, { pascalCase: true })
return camelStr
}
Run Code Online (Sandbox Code Playgroud)
包/ B/src目录/分型/驼峰/ 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
}
Run Code Online (Sandbox Code Playgroud)
现在,如果您将目录更改为打包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'.
Run Code Online (Sandbox Code Playgroud)
TSLint不识别包B所依赖的类型,但它只是在从包A运行tslint时抱怨这个(不是预期的).在包B内,tslint不会抱怨(如预期的那样).
题
当然我可以手动添加camelcase
内部包A的类型,但这似乎明显违反了关注点的分离:包A不应该知道包B依赖于包camelcase,或X或Y.它只是应该了解包B的公共API,即dependedFn
.
如何设置tslint,以便在使用纱线工作区时正确解析这些间接输入定义?
您可以通过从以下位置删除这些行来使 TSLint 在您的情况下工作tsconfig.json
:
"baseUrl": "./packages",
"paths": {
"*": ["./*/src"]
},
Run Code Online (Sandbox Code Playgroud)
这些行告诉 TypeScript 编译器和 TSLint,在导入模块a
和包时,它们不应将其视为包,而是应使用和参数解析各个 TypeScript 文件,然后编译各个 TypeScript 文件。此行为记录在 TypeScript 文档的模块解析 -> 路径映射部分中:b
baseUrl
paths
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 使用 TypeScript 编译器 API 根据tsconfig.json
. 但你的 TypeScript 编译器不使用tsconfig.json
规则。在实际项目中,这两个命令都会使用tsconfig.json
当您也开始使用tsconfig.json
编译时,您将遇到与 TSLint 相同的解决二级依赖类型的问题:
$ 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'
~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
发生这种情况是因为路径映射模块导入按设计不同编译,然后
根据第一部分中指定的node_modules
TypeScript 文档
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 编译器。