Skip to content

Commit 67706e7

Browse files
feat(eslint-plugin): add key-spacing rule extension for interface & type declarations (#6211)
* 🚧 key-spacing for interface on default settings * 🚧 Support type literals as welll * 🚧 Add full typing for the options * 🚧 Add 'mode' param * 🐛 Fix index signatures * ✨ Support classes * 🩹 fixes * ✅ Add tests on mode, multiLine, singleLine * 🏷️ Allow options.multiline.align to be an object * 🎨 Use ast utils to locate last character before token * ✨ Support comments in-between properties * ✅ Add test cases for nested type declarations & multiline type annotations * ✨ Autofix for non-aligned values * ✨ Autofix for aligned values * ✏️ * 🚨 * 🐛 Support optional ? token * ✅ Add tests with class property assignments * 📝 Add documentation on key-spacing * 🎨 Use .at() to access last element of array * ✅ Fix tests * fixup! ✅ Fix tests * ✅ Add some coverage * 🐛 Fix edge case in determining aligned groups In case there is three statements in one line, and one statement in the line after * ⚡️ Use Array.concat instead of .push(...) .push could error if 60k + arguments * 🎨 Improve readability * 🎨 Use tempate literals in tests * ✅ Add test with anonymous types * ✅ Add test with quoted keys * ➕ Add grapheme-splitter to deal with emojis * ✅ Add test case for multiline comments * 🚨 Remove 'in' statements, reduce amount of null-assertions * ✅ Add test case for properties without type annotation or assignments * ✅ Add wacky test cases * ✅ Add coverage * ✅ Add coverage, again * ✅ Add coverage, again * ✅ Add coverage when align is an object, but align.on is missing It defaults to 'colon' in this case * KeyTypeNodeWithTypeAnnotation * Extract to shared helper Co-authored-by: Josh Goldberg <[email protected]>
1 parent 09d57ce commit 67706e7

File tree

11 files changed

+1789
-16
lines changed

11 files changed

+1789
-16
lines changed

Diff for: packages/eslint-plugin/docs/rules/key-spacing.md

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
description: 'Enforce consistent spacing between property names and type annotations in types and interfaces.'
3+
---
4+
5+
> 🛑 This file is source code, not the primary documentation location! 🛑
6+
>
7+
> See **https://typescript-eslint.io/rules/key-spacing** for documentation.
8+
9+
## Examples
10+
11+
This rule extends the base [`eslint/keyword-spacing`](https://eslint.org/docs/rules/key-spacing) rule.
12+
This version adds support for type annotations on interfaces, classes and type literals properties.

Diff for: packages/eslint-plugin/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
"debug": "^4.3.4",
5151
"grapheme-splitter": "^1.0.4",
5252
"ignore": "^5.2.0",
53+
"grapheme-splitter": "^1.0.4",
5354
"natural-compare-lite": "^1.4.0",
5455
"regexpp": "^3.2.0",
5556
"semver": "^7.3.7",

Diff for: packages/eslint-plugin/src/configs/all.ts

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ export = {
3737
'@typescript-eslint/indent': 'error',
3838
'init-declarations': 'off',
3939
'@typescript-eslint/init-declarations': 'error',
40+
'key-spacing': 'off',
41+
'@typescript-eslint/key-spacing': 'error',
4042
'keyword-spacing': 'off',
4143
'@typescript-eslint/keyword-spacing': 'error',
4244
'lines-between-class-members': 'off',

Diff for: packages/eslint-plugin/src/rules/ban-ts-comment.ts

+2-16
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,7 @@
11
import { AST_TOKEN_TYPES } from '@typescript-eslint/utils';
2-
import GraphemeSplitter from 'grapheme-splitter';
32

43
import * as util from '../util';
54

6-
let splitter: GraphemeSplitter;
7-
function isASCII(value: string): boolean {
8-
return /^[\u0020-\u007f]*$/u.test(value);
9-
}
10-
function getStringLength(value: string): number {
11-
if (isASCII(value)) {
12-
return value.length;
13-
}
14-
15-
splitter ??= new GraphemeSplitter();
16-
17-
return splitter.countGraphemes(value);
18-
}
19-
205
type DirectiveConfig =
216
| boolean
227
| 'allow-with-description'
@@ -163,7 +148,8 @@ export default util.createRule<[Options], MessageIds>({
163148
} = options;
164149
const format = descriptionFormats.get(fullDirective);
165150
if (
166-
getStringLength(description.trim()) < minimumDescriptionLength
151+
util.getStringLength(description.trim()) <
152+
minimumDescriptionLength
167153
) {
168154
context.report({
169155
data: { directive, minimumDescriptionLength },

Diff for: packages/eslint-plugin/src/rules/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import explicitModuleBoundaryTypes from './explicit-module-boundary-types';
2222
import funcCallSpacing from './func-call-spacing';
2323
import indent from './indent';
2424
import initDeclarations from './init-declarations';
25+
import keySpacing from './key-spacing';
2526
import keywordSpacing from './keyword-spacing';
2627
import linesBetweenClassMembers from './lines-between-class-members';
2728
import memberDelimiterStyle from './member-delimiter-style';
@@ -153,6 +154,7 @@ export default {
153154
'func-call-spacing': funcCallSpacing,
154155
indent: indent,
155156
'init-declarations': initDeclarations,
157+
'key-spacing': keySpacing,
156158
'keyword-spacing': keywordSpacing,
157159
'lines-between-class-members': linesBetweenClassMembers,
158160
'member-delimiter-style': memberDelimiterStyle,

0 commit comments

Comments
 (0)