UNPKG

5.66 kBJavaScriptView Raw
1"use strict";
2var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 if (k2 === undefined) k2 = k;
4 Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5}) : (function(o, m, k, k2) {
6 if (k2 === undefined) k2 = k;
7 o[k2] = m[k];
8}));
9var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10 Object.defineProperty(o, "default", { enumerable: true, value: v });
11}) : function(o, v) {
12 o["default"] = v;
13});
14var __importStar = (this && this.__importStar) || function (mod) {
15 if (mod && mod.__esModule) return mod;
16 var result = {};
17 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18 __setModuleDefault(result, mod);
19 return result;
20};
21Object.defineProperty(exports, "__esModule", { value: true });
22const utils_1 = require("@typescript-eslint/utils");
23const util = __importStar(require("../util"));
24exports.default = util.createRule({
25 name: 'consistent-type-definitions',
26 meta: {
27 type: 'suggestion',
28 docs: {
29 description: 'Consistent with type definition either `interface` or `type`',
30 // too opinionated to be recommended
31 recommended: false,
32 },
33 messages: {
34 interfaceOverType: 'Use an `interface` instead of a `type`.',
35 typeOverInterface: 'Use a `type` instead of an `interface`.',
36 },
37 schema: [
38 {
39 enum: ['interface', 'type'],
40 },
41 ],
42 fixable: 'code',
43 },
44 defaultOptions: ['interface'],
45 create(context, [option]) {
46 const sourceCode = context.getSourceCode();
47 /**
48 * Iterates from the highest parent to the currently traversed node
49 * to determine whether any node in tree is globally declared module declaration
50 */
51 function isCurrentlyTraversedNodeWithinModuleDeclaration() {
52 return context
53 .getAncestors()
54 .some(node => node.type === utils_1.AST_NODE_TYPES.TSModuleDeclaration &&
55 node.declare &&
56 node.global);
57 }
58 return Object.assign(Object.assign({}, (option === 'interface' && {
59 "TSTypeAliasDeclaration[typeAnnotation.type='TSTypeLiteral']"(node) {
60 context.report({
61 node: node.id,
62 messageId: 'interfaceOverType',
63 fix(fixer) {
64 var _a;
65 const typeNode = (_a = node.typeParameters) !== null && _a !== void 0 ? _a : node.id;
66 const fixes = [];
67 const firstToken = sourceCode.getTokenBefore(node.id);
68 if (firstToken) {
69 fixes.push(fixer.replaceText(firstToken, 'interface'));
70 fixes.push(fixer.replaceTextRange([typeNode.range[1], node.typeAnnotation.range[0]], ' '));
71 }
72 const afterToken = sourceCode.getTokenAfter(node.typeAnnotation);
73 if (afterToken &&
74 afterToken.type === utils_1.AST_TOKEN_TYPES.Punctuator &&
75 afterToken.value === ';') {
76 fixes.push(fixer.remove(afterToken));
77 }
78 return fixes;
79 },
80 });
81 },
82 })), (option === 'type' && {
83 TSInterfaceDeclaration(node) {
84 context.report({
85 node: node.id,
86 messageId: 'typeOverInterface',
87 /**
88 * remove automatically fix when the interface is within a declare global
89 * @see {@link https://github.com/typescript-eslint/typescript-eslint/issues/2707}
90 */
91 fix: isCurrentlyTraversedNodeWithinModuleDeclaration()
92 ? null
93 : (fixer) => {
94 var _a, _b;
95 const typeNode = (_a = node.typeParameters) !== null && _a !== void 0 ? _a : node.id;
96 const fixes = [];
97 const firstToken = sourceCode.getTokenBefore(node.id);
98 if (firstToken) {
99 fixes.push(fixer.replaceText(firstToken, 'type'));
100 fixes.push(fixer.replaceTextRange([typeNode.range[1], node.body.range[0]], ' = '));
101 }
102 if (node.extends) {
103 node.extends.forEach(heritage => {
104 const typeIdentifier = sourceCode.getText(heritage);
105 fixes.push(fixer.insertTextAfter(node.body, ` & ${typeIdentifier}`));
106 });
107 }
108 if (((_b = node.parent) === null || _b === void 0 ? void 0 : _b.type) ===
109 utils_1.AST_NODE_TYPES.ExportDefaultDeclaration) {
110 fixes.push(fixer.removeRange([node.parent.range[0], node.range[0]]), fixer.insertTextAfter(node.body, `\nexport default ${node.id.name}`));
111 }
112 return fixes;
113 },
114 });
115 },
116 }));
117 },
118});
119//# sourceMappingURL=consistent-type-definitions.js.map
\No newline at end of file