V TypeScriptu, je možné využít eslint pravidlo no-relative-parent-imports pro hodnoty, ale stále mít povoleno importovat typy z nadřazených modulů?
Rád používám pravidlo eslint imports/no-relative-parent-imports, abych udržel závislosti mezi různými částmi kódu přehledné a kód snadno testovatelný.
S TypeScriptem narazím na tento problém: stále potřebuji importovat typy z nadřazených modulů, abych mohl provádět dependency injection (pokud typy nezduplikuji pro každé použití)
Například, pokud jen přeložím kód z dokumentace pravidla do TypeScriptu, stane se z toho toto:
// ./add.ts
export default function add (numbers: number[]): number {
return numbers.reduce((sum, n) => sum + n, 0)
}
export type Add = typeof add
// three.ts
import { Add } from '../add' // <--- Relative import still needed to implement
// dependency injection
export default function three(add: Add) : number {
return add([1, 2]);
}
Samozřejmě by tato úprava pravidlo nepřekročila kvůli relativnímu importu.
Jediný způsob, který vidím, by byl duplikování typu, což by fungovalo kvůli strukturní povaze TypeScriptu, ale na velkém projektu by to bylo zdlouhavé.
Existuje pravidlo, které vynucuje dependency injection, ale zároveň mi dovolí importovat typy deklarované v závislostech? Protože potřebuji rozhraní, typy parametrů funkcí atd...
Odpověď č. 1
Je možné to implementovat s eslint-plugin-local-rules.
Nejprve nainstalujte plugin local-rules :
npm install eslint-plugin-local-rules --save-dev
Použijte to k zavedení pravidla, které dosáhne požadovaného cíle :
// eslint-local-rules.cjs
'use strict'
module.exports = {
'no-relative-parent-imports': {
meta: {
docs: {
description: 'disallow identifiers',
category: 'Possible Errors',
recommended: false,
},
schema: [],
},
create: function (context) {
return {
ImportDeclaration: function (node) {
const tsNode = context.parserServices.esTreeNodeToTSNodeMap.get(node)
if (tsNode.importClause.isTypeOnly) {
return
}
if (tsNode.moduleSpecifier.text.includes('..')) {
context.report({
node: node,
message: 'Import from relative parent. Une `import type` for types and dependency injection for values.',
})
}
},
}
},
},
}
A nakonec nakonfigurujte eslint tak, aby jej používal. Minimální konfigurace k tomu:
{
"parser": "@typescript-eslint/parser",
"plugins": [
"local-rules"
],
"rules": {
"local-rules/no-relative-parent-imports": "error"
}
}
