Context
Yarn workspaces provide for a convenient way to depend on packages in a mono-repo. When package A depends on package B, the interfaces etc. defined in package B are appropriately resolved in package A.
Problem
I am facing an issue where if package B is depending on an external library, but that external library lacks typings, and therefore package B has created its own some-library.d.ts
file. When using tslint
to lint package A, this custom definition file is resolved properly for expressions in package B, but not for expressions in package A that are working with types from package B.
I've pushed a simplified example of this problem here:
https://github.com/tommedema/tslint-yarn-workspaces
The core of it is as follows.
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
}
Now if you change directory to package a
and run yarn build
, it works just fine. But if you run yarn lint
, it will throw:
$ 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 does not recognize the typings that are depended on by package B, but it only complains about this when running tslint from package A (not expected). Inside package B, tslint does not complain (as expected).
Question
Of course I could manually add the typings of camelcase
inside package A, but that seems like an obvious violation of separation of concerns: package A is not supposed to know that package B depends on package camelcase, or X or Y. It is only supposed to know about package B's public API, i.e. the dependedFn
.
How can I setup tslint such that it correctly resolves these indirect typing definitions when using yarn workspaces?