Skip to content

Commit 18f9ae6

Browse files
authored
build: set up typescript-eslint (#542)
* build: set up typescript-eslint This change adds typescript-eslint to our config and fixes a miss in the original TypeScript migration where we weren't linting the newly renamed `ts` files. This also addresses violations found from both sets of config changes. * changed example in no-property-in-node to js
1 parent 5f11f54 commit 18f9ae6

20 files changed

+77
-78
lines changed

docs/rules/no-property-in-node.md

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ Instead, checking a node's `type` property is generally considered preferable.
1313

1414
Examples of **incorrect** code for this rule:
1515

16-
```ts
17-
/* eslint eslint-plugin/no-property-in-node: error */
18-
16+
```js
1917
/** @type {import('eslint').Rule.RuleModule} */
2018
module.exports = {
2119
meta: {
@@ -25,7 +23,7 @@ module.exports = {
2523
return {
2624
'ClassDeclaration, FunctionDeclaration'(node) {
2725
if ('superClass' in node) {
28-
console.log('This is a class declaration:', node);
26+
// This is a class declaration
2927
}
3028
},
3129
};
@@ -35,9 +33,7 @@ module.exports = {
3533

3634
Examples of **correct** code for this rule:
3735

38-
```ts
39-
/* eslint eslint-plugin/no-property-in-node: error */
40-
36+
```js
4137
/** @type {import('eslint').Rule.RuleModule} */
4238
module.exports = {
4339
meta: {
@@ -47,7 +43,7 @@ module.exports = {
4743
return {
4844
'ClassDeclaration, FunctionDeclaration'(node) {
4945
if (node.type === 'ClassDeclaration') {
50-
console.log('This is a class declaration:', node);
46+
// This is a class declaration;
5147
}
5248
},
5349
};

eslint.config.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import path from 'node:path';
22
import { fileURLToPath } from 'node:url';
33
import js from '@eslint/js';
44
import { FlatCompat } from '@eslint/eslintrc';
5-
import { defineConfig } from 'eslint/config';
65
import markdown from 'eslint-plugin-markdown';
76
import pluginN from 'eslint-plugin-n';
7+
import tseslint from 'typescript-eslint';
88
import eslintPlugin from './lib/index.js';
99

1010
const dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -13,14 +13,14 @@ const compat = new FlatCompat({
1313
recommendedConfig: js.configs.recommended,
1414
});
1515

16-
export default defineConfig([
16+
export default tseslint.config([
1717
// Global ignores
1818
{
19-
ignores: ['node_modules', 'coverage', 'dist'],
19+
ignores: ['node_modules', 'coverage', 'dist', 'tests/lib/fixtures'],
2020
},
2121
// Global settings
2222
{
23-
languageOptions: { sourceType: 'module' },
23+
languageOptions: { parser: tseslint.parser, sourceType: 'module' },
2424
},
2525
...compat.extends(
2626
'not-an-aardvark/node',
@@ -41,11 +41,18 @@ export default defineConfig([
4141
'unicorn/no-null': 'off',
4242
'unicorn/prefer-module': 'off',
4343
'unicorn/prevent-abbreviations': 'off',
44+
'unicorn/no-nested-ternary': 'off',
4445
},
4546
},
47+
// TypeScript rules
48+
tseslint.configs.recommended.map((config) => ({
49+
files: ['**/*.ts', '**/*.mts', '**/*.cts'],
50+
...config,
51+
rules: { ...config.rules, 'n/no-missing-import': 'off' },
52+
})),
4653
{
4754
// Apply eslint-plugin rules to our own rules/tests (but not docs).
48-
files: ['lib/**/*.js', 'tests/**/*.js'],
55+
files: ['lib/**/*.ts', 'tests/**/*.ts'],
4956
plugins: { 'eslint-plugin': eslintPlugin },
5057
rules: {
5158
...eslintPlugin.configs.all.rules,
@@ -67,12 +74,14 @@ export default defineConfig([
6774
},
6875
{
6976
// Markdown JS code samples in documentation:
70-
files: ['**/*.md/*.js'],
77+
files: ['**/*.md/*.js', '**/*.md/*.ts'],
7178
plugins: { markdown },
7279
linterOptions: { noInlineConfig: true },
7380
rules: {
7481
'no-undef': 'off',
7582
'no-unused-vars': 'off',
83+
'@typescript-eslint/no-unused-vars': 'off',
84+
7685
strict: 'off',
7786

7887
'@eslint-community/eslint-comments/require-description': 'off',

lib/index.ts

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,24 +41,14 @@ import testCaseShorthandStrings from './rules/test-case-shorthand-strings.js';
4141

4242
const require = createRequire(import.meta.url);
4343

44-
const packageMetadata = require("../package.json") as {
45-
name: string;
46-
version: string;
44+
const packageMetadata = require('../package.json') as {
45+
name: string;
46+
version: string;
4747
};
4848

4949
const PLUGIN_NAME = packageMetadata.name.replace(/^eslint-plugin-/, '');
50-
const CONFIG_NAMES = [
51-
'all',
52-
'all-type-checked',
53-
'recommended',
54-
'rules',
55-
'tests',
56-
'rules-recommended',
57-
'tests-recommended',
58-
] as const;
59-
type ConfigName = (typeof CONFIG_NAMES)[number];
6050

61-
const configFilters: Record<ConfigName, (rule: Rule.RuleModule) => boolean> = {
51+
const configFilters: Record<string, (rule: Rule.RuleModule) => boolean> = {
6252
all: (rule: Rule.RuleModule) =>
6353
!(
6454
rule.meta?.docs &&
@@ -75,7 +65,7 @@ const configFilters: Record<ConfigName, (rule: Rule.RuleModule) => boolean> = {
7565
configFilters.recommended(rule) && configFilters.tests(rule),
7666
};
7767

78-
const createConfig = (configName: ConfigName): Linter.Config => ({
68+
const createConfig = (configName: string): Linter.Config => ({
7969
name: `${PLUGIN_NAME}/${configName}`,
8070
plugins: {
8171
get [PLUGIN_NAME](): ESLint.Plugin {

lib/rules/no-meta-schema-default.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,9 @@ const rule: Rule.RuleModule = {
8383

8484
case 'properties': {
8585
if ('properties' in value && Array.isArray(value.properties)) {
86-
for (const property of value.properties) {
87-
if (
88-
'value' in property &&
89-
property.value.type === 'ObjectExpression'
90-
) {
91-
checkSchemaElement(property.value);
86+
for (const prop of value.properties) {
87+
if ('value' in prop && prop.value.type === 'ObjectExpression') {
88+
checkSchemaElement(prop.value);
9289
}
9390
}
9491
}

lib/rules/no-missing-message-ids.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ const rule: Rule.RuleModule = {
7272
collectReportViolationAndSuggestionData(reportInfo);
7373
for (const messageId of reportMessagesAndDataArray
7474
.map((obj) => obj.messageId)
75-
.filter((messageId) => !!messageId)) {
75+
.filter((id) => !!id)) {
7676
const values =
7777
messageId.type === 'Literal'
7878
? [messageId]

lib/rules/no-missing-placeholders.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ const rule: Rule.RuleModule = {
111111
let match: RegExpExecArray | null;
112112

113113
const messageText: string =
114-
// @ts-expect-error
114+
// @ts-expect-error -- Property 'value' does not exist on type 'ArrayExpression'.ts(2339)
115115
message.value || messageStaticValue.value;
116116
while ((match = PLACEHOLDER_MATCHER.exec(messageText))) {
117117
const matchingProperty =

lib/rules/no-only-tests.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,19 @@ const rule: Rule.RuleModule = {
5656
sourceCode.getTokenBefore(onlyProperty);
5757
const tokenAfter =
5858
sourceCode.getTokenAfter(onlyProperty);
59-
if ((tokenBefore && tokenAfter) &&
59+
if (
60+
tokenBefore &&
61+
tokenAfter &&
6062
((isCommaToken(tokenBefore) &&
6163
isCommaToken(tokenAfter)) || // In middle of properties
62-
(isOpeningBraceToken(tokenBefore) &&
63-
isCommaToken(tokenAfter))) // At beginning of properties
64+
(isOpeningBraceToken(tokenBefore) &&
65+
isCommaToken(tokenAfter))) // At beginning of properties
6466
) {
6567
yield fixer.remove(tokenAfter); // Remove extra comma.
6668
}
67-
if ((tokenBefore && tokenAfter) &&
69+
if (
70+
tokenBefore &&
71+
tokenAfter &&
6872
isCommaToken(tokenBefore) &&
6973
isClosingBraceToken(tokenAfter)
7074
) {

lib/rules/no-unused-message-ids.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ const rule: Rule.RuleModule = {
103103
collectReportViolationAndSuggestionData(reportInfo);
104104
for (const messageId of reportMessagesAndDataArray
105105
.map((obj) => obj.messageId)
106-
.filter((messageId) => !!messageId)) {
106+
.filter((id) => !!id)) {
107107
const values =
108108
messageId.type === 'Literal'
109109
? [messageId]

lib/rules/no-unused-placeholders.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ const rule: Rule.RuleModule = {
103103
data.type === 'ObjectExpression'
104104
) {
105105
const messageValue: string =
106-
// @ts-expect-error
106+
// @ts-expect-error -- Property 'value' does not exist on type 'SimpleCallExpression'.ts(2339)
107107
message.value || messageStaticValue.value;
108108
// https://github.com/eslint/eslint/blob/2874d75ed8decf363006db25aac2d5f8991bd969/lib/linter.js#L986
109109
const PLACEHOLDER_MATCHER = /{{\s*([^{}]+?)\s*}}/g;

lib/rules/no-useless-token-range.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,7 @@
33
* @author Teddy Katz
44
*/
55
import type { Rule } from 'eslint';
6-
import type {
7-
CallExpression,
8-
Expression,
9-
MemberExpression,
10-
Node,
11-
Property,
12-
SpreadElement,
13-
} from 'estree';
6+
import type { Expression, MemberExpression, SpreadElement } from 'estree';
147

158
import { getKeyName, getSourceCodeIdentifiers } from '../utils.js';
169

0 commit comments

Comments
 (0)