Skip to content

Commit 67fd797

Browse files
committed
fix(tsl-dx): Distinguish type vs value imports for unit in nullish rule
- Handle undefined as both Identifier (expressions) and UndefinedKeyword (types) - Use import type for type annotations, regular import for values
1 parent bc62afe commit 67fd797

File tree

2 files changed

+48
-5
lines changed

2 files changed

+48
-5
lines changed

packages/tsl-dx/src/rules/nullish.test.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,33 @@ test("nullish", () => {
1818
{
1919
message: suggestions.replaceWithExpression({ expr: "unit" }),
2020
output: tsx`
21-
import { unit } from '@local/eff';
21+
import type { unit } from '@local/eff';
2222
let undef: unit;
2323
`,
2424
},
2525
],
2626
},
2727
],
2828
},
29+
{
30+
code: tsx`
31+
let undef = undefined;
32+
`,
33+
errors: [
34+
{
35+
message: messages.useUnitForUndefined,
36+
suggestions: [
37+
{
38+
message: suggestions.replaceWithExpression({ expr: "unit" }),
39+
output: tsx`
40+
import { unit } from '@local/eff';
41+
let undef = unit;
42+
`,
43+
},
44+
],
45+
},
46+
],
47+
},
2948
{
3049
code: tsx`
3150
if (a === null) { }
@@ -167,7 +186,7 @@ test("nullish", () => {
167186
{
168187
message: suggestions.replaceWithExpression({ expr: "unit" }),
169188
output: tsx`
170-
import { unit } from '@local/eff';
189+
import type { unit } from '@local/eff';
171190
let a: unit;
172191
let b: undefined;
173192
`,
@@ -180,7 +199,7 @@ test("nullish", () => {
180199
{
181200
message: suggestions.replaceWithExpression({ expr: "unit" }),
182201
output: tsx`
183-
import { unit } from '@local/eff';
202+
import type { unit } from '@local/eff';
184203
let a: undefined;
185204
let b: unit;
186205
`,

packages/tsl-dx/src/rules/nullish.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ export const nullish = defineRule((options?: nullishOptions) => ({
2323
};
2424
},
2525
visitor: {
26-
UndefinedKeyword(ctx, node) {
26+
Identifier(ctx, node) {
2727
if (node.getSourceFile().isDeclarationFile) return;
28+
if (node.parent.kind === SyntaxKind.BinaryExpression || node.text !== "undefined") return;
2829
ctx.report({
2930
node,
3031
message: messages.useUnitForUndefined,
@@ -46,6 +47,29 @@ export const nullish = defineRule((options?: nullishOptions) => ({
4647
],
4748
});
4849
},
50+
UndefinedKeyword(ctx, node) {
51+
if (node.getSourceFile().isDeclarationFile) return;
52+
ctx.report({
53+
node,
54+
message: messages.useUnitForUndefined,
55+
suggestions: [
56+
{
57+
message: suggestions.replaceWithExpression({ expr: "unit" }),
58+
changes: [
59+
{
60+
node,
61+
newText: "unit",
62+
},
63+
{
64+
start: 0,
65+
end: 0,
66+
newText: `import type { unit } from '${ctx.data.runtimeLibrary}';\n`,
67+
},
68+
],
69+
},
70+
],
71+
});
72+
},
4973
BinaryExpression(ctx, node) {
5074
if (node.getSourceFile().isDeclarationFile) return;
5175
const newOperatorText = match(node.operatorToken.kind)
@@ -58,7 +82,7 @@ export const nullish = defineRule((options?: nullishOptions) => ({
5882
case SyntaxKind.NullKeyword:
5983
return true;
6084
case SyntaxKind.Identifier:
61-
return n.escapedText === "undefined";
85+
return n.text === "unit" || n.text === "undefined";
6286
default:
6387
return false;
6488
}

0 commit comments

Comments
 (0)