Skip to content

Commit 98c6e1c

Browse files
authored
Merge branch 'sindresorhus:main' into SplitOnSpread
2 parents 087e110 + 57fef12 commit 98c6e1c

File tree

6 files changed

+121
-71
lines changed

6 files changed

+121
-71
lines changed

lint-rules/import-path.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import path from 'node:path';
2+
3+
export const importPathRule = /** @type {const} */ ({
4+
meta: {
5+
type: 'problem',
6+
docs: {
7+
description: 'Enforces import paths to end with a \'.d.ts\' extension.',
8+
},
9+
fixable: 'code',
10+
messages: {
11+
incorrectImportPath:
12+
'Import path \'{{importPath}}\' must end with a \'.d.ts\' extension. Use \'{{fixedImportPath}}\' instead.',
13+
},
14+
schema: [],
15+
},
16+
defaultOptions: [],
17+
create(context) {
18+
return {
19+
ImportDeclaration(node) {
20+
const importPath = node.source.value;
21+
22+
// Skip if not relative path
23+
if (!(importPath.startsWith('./') || importPath.startsWith('../'))) {
24+
return;
25+
}
26+
27+
const filename = path.basename(importPath);
28+
const firstDotIndex = filename.indexOf('.');
29+
const extension = firstDotIndex === -1 ? '' : filename.slice(firstDotIndex);
30+
31+
// Skip if the import path already ends with `.d.ts`
32+
if (extension === '.d.ts') {
33+
return;
34+
}
35+
36+
const importPathWithoutExtension = extension.length > 0
37+
? importPath.slice(0, -extension.length)
38+
: importPath;
39+
const fixedImportPath = `${importPathWithoutExtension}.d.ts`;
40+
41+
context.report({
42+
node: node.source,
43+
messageId: 'incorrectImportPath',
44+
fix(fixer) {
45+
return fixer.replaceText(node.source, `'${fixedImportPath}'`);
46+
},
47+
data: {importPath, fixedImportPath},
48+
});
49+
},
50+
};
51+
},
52+
});

package.json

Lines changed: 1 addition & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -58,75 +58,8 @@
5858
"npm-run-all2": "^8.0.1",
5959
"tsd": "^0.32.0",
6060
"typescript": "~5.8.3",
61-
"xo": "^1.0.0"
61+
"xo": "^1.0.5"
6262
},
63-
"xo": [
64-
{
65-
"rules": {
66-
"@typescript-eslint/no-extraneous-class": "off",
67-
"@typescript-eslint/ban-ts-comment": "off",
68-
"@typescript-eslint/ban-types": "off",
69-
"@typescript-eslint/naming-convention": "off",
70-
"@typescript-eslint/no-redeclare": "off",
71-
"@typescript-eslint/no-confusing-void-expression": "off",
72-
"@typescript-eslint/no-unsafe-argument": "off",
73-
"@typescript-eslint/no-restricted-types": "off",
74-
"@typescript-eslint/no-empty-object-type": "off",
75-
"@typescript-eslint/no-unsafe-function-type": "off",
76-
"@typescript-eslint/no-deprecated": "off",
77-
"@typescript-eslint/no-wrapper-object-types": "off",
78-
"@typescript-eslint/consistent-indexed-object-style": "off",
79-
"@stylistic/quote-props": "off",
80-
"@stylistic/function-paren-newline": "off",
81-
"@stylistic/object-curly-newline": "off",
82-
"n/file-extension-in-import": "off",
83-
"object-curly-newline": [
84-
"error",
85-
{
86-
"multiline": true,
87-
"consistent": true
88-
}
89-
],
90-
"import-x/consistent-type-specifier-style": [
91-
"error",
92-
"prefer-top-level"
93-
]
94-
}
95-
},
96-
{
97-
"files": "source/**/*.d.ts",
98-
"rules": {
99-
"no-restricted-imports": [
100-
"error",
101-
{
102-
"paths": ["tsd", "expect-type"],
103-
"patterns": [
104-
{
105-
"group": ["*.js", "*.ts", "!*.d.ts"],
106-
"message": "Use `.d.ts` extension."
107-
}
108-
]
109-
}
110-
]
111-
}
112-
},
113-
{
114-
"files": "test-d/**/*.ts",
115-
"rules": {
116-
"no-restricted-imports": [
117-
"error",
118-
{
119-
"patterns": [
120-
{
121-
"group": ["*.js", "*.ts", "!*.d.ts"],
122-
"message": "Use `.d.ts` extension."
123-
}
124-
]
125-
}
126-
]
127-
}
128-
}
129-
],
13063
"tsd": {
13164
"compilerOptions": {
13265
"noUnusedLocals": false

source/pick-deep.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import type {BuildObject, BuildTuple, NonRecursiveType, ObjectValue} from './internal/index.d.ts';
22
import type {IsNever} from './is-never.d.ts';
33
import type {Paths} from './paths.d.ts';
4-
import type {Simplify} from './simplify.d.d.ts';
5-
import type {UnionToIntersection} from './union-to-intersection.d.d.ts';
4+
import type {Simplify} from './simplify.d.ts';
5+
import type {UnionToIntersection} from './union-to-intersection.d.ts';
66
import type {UnknownArray} from './unknown-array.d.ts';
77

88
/**

test-d/internal/is-number-like.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {expectType} from 'tsd';
2-
import type {IsNumberLike} from '../../source/internal/numeric.d.d.ts';
2+
import type {IsNumberLike} from '../../source/internal/numeric.d.ts';
33

44
expectType<IsNumberLike<'1'>>(true);
55
expectType<IsNumberLike<1>>(true);

tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"extends": "@sindresorhus/tsconfig",
33
"compilerOptions": {
44
"noEmit": true,
5+
"allowJs": true,
56
"noUnusedLocals": false, // Allow unused variables in test-d/*.ts files
67
"module": "node18",
78
"target": "ES2023", // Node.js 20

xo.config.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// @ts-check
2+
import {importPathRule} from './lint-rules/import-path.js';
3+
4+
/** @type {import('xo').FlatXoConfig} */
5+
const xoConfig = [
6+
{
7+
rules: {
8+
'@typescript-eslint/no-extraneous-class': 'off',
9+
'@typescript-eslint/ban-ts-comment': 'off',
10+
'@typescript-eslint/ban-types': 'off',
11+
'@typescript-eslint/naming-convention': 'off',
12+
'@typescript-eslint/no-redeclare': 'off',
13+
'@typescript-eslint/no-confusing-void-expression': 'off',
14+
'@typescript-eslint/no-unsafe-argument': 'off',
15+
'@typescript-eslint/no-restricted-types': 'off',
16+
'@typescript-eslint/no-empty-object-type': 'off',
17+
'@typescript-eslint/no-unsafe-function-type': 'off',
18+
'@typescript-eslint/no-deprecated': 'off',
19+
'@typescript-eslint/no-wrapper-object-types': 'off',
20+
'@typescript-eslint/consistent-indexed-object-style': 'off',
21+
'@stylistic/quote-props': 'off',
22+
'@stylistic/function-paren-newline': 'off',
23+
'@stylistic/object-curly-newline': 'off',
24+
'n/file-extension-in-import': 'off',
25+
'object-curly-newline': [
26+
'error',
27+
{
28+
multiline: true,
29+
consistent: true,
30+
},
31+
],
32+
'import-x/consistent-type-specifier-style': [
33+
'error',
34+
'prefer-top-level',
35+
],
36+
},
37+
},
38+
{
39+
files: 'source/**/*.d.ts',
40+
rules: {
41+
'no-restricted-imports': [
42+
'error',
43+
{
44+
paths: ['tsd', 'expect-type'],
45+
},
46+
],
47+
},
48+
},
49+
{
50+
files: ['source/**/*.d.ts', 'test-d/**/*.ts'],
51+
plugins: {
52+
'type-fest': {
53+
rules: {
54+
'import-path': importPathRule,
55+
},
56+
},
57+
},
58+
rules: {
59+
'type-fest/import-path': 'error',
60+
},
61+
},
62+
];
63+
64+
export default xoConfig;

0 commit comments

Comments
 (0)