Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7151489

Browse files
feat(eslint-plugin): [prefer-nullish-coalescing] support if statement assignment (??=) and fix several minor bugs (typescript-eslint#10861)
* support if statement assignment * improve logic * fix false positive * handle computed expression (patch for existing issue) * add tests * simplify and add test * fix error * add "IfStatement without curly brackets" use case * add test * after review * forgot the `noFormat` * fix test * Handle comments * fix naming and add test * improve indentation * fix type * simplify * remove duplicated test case --------- Co-authored-by: Kirk Waiblinger <[email protected]>
1 parent 27bdddb commit 7151489

File tree

7 files changed

+1293
-185
lines changed

7 files changed

+1293
-185
lines changed

packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,54 @@ This rule reports when you may consider replacing:
1717
- An `||` operator with `??`
1818
- An `||=` operator with `??=`
1919
- Ternary expressions (`?:`) that are equivalent to `||` or `??` with `??`
20+
- Assignment expressions (`=`) that can be safely replaced by `??=`
21+
22+
## Examples
23+
24+
<Tabs>
25+
<TabItem value="❌ Incorrect">
26+
27+
```ts
28+
declare const a: string | null;
29+
declare const b: string | null;
30+
31+
const c = a || b;
32+
33+
declare let foo: { a: string } | null;
34+
declare function makeFoo(): { a: string };
35+
36+
function lazyInitializeFooByTruthiness() {
37+
if (!foo) {
38+
foo = makeFoo();
39+
}
40+
}
41+
42+
function lazyInitializeFooByNullCheck() {
43+
if (foo == null) {
44+
foo = makeFoo();
45+
}
46+
}
47+
```
48+
49+
</TabItem>
50+
<TabItem value="✅ Correct">
51+
52+
```ts
53+
declare const a: string | null;
54+
declare const b: string | null;
55+
56+
const c = a ?? b;
57+
58+
declare let foo: { a: string } | null;
59+
declare function makeFoo(): { a: string };
60+
61+
function lazyInitializeFoo() {
62+
foo ??= makeFoo();
63+
}
64+
```
65+
66+
</TabItem>
67+
</Tabs>
2068

2169
:::caution
2270
This rule will not work as expected if [`strictNullChecks`](https://www.typescriptlang.org/tsconfig#strictNullChecks) is not enabled.
@@ -255,3 +303,4 @@ If you are not using TypeScript 3.7 (or greater), then you will not be able to u
255303

256304
- [TypeScript 3.7 Release Notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html)
257305
- [Nullish Coalescing Operator Proposal](https://github.com/tc39/proposal-nullish-coalescing/)
306+
- [`logical-assignment-operators`](https://eslint.org/docs/latest/rules/logical-assignment-operators)

packages/eslint-plugin/src/rules/consistent-type-exports.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -203,13 +203,11 @@ export default createRule<Options, MessageIds>({
203203
// Cache the first encountered exports for the package. We will need to come
204204
// back to these later when fixing the problems.
205205
if (node.exportKind === 'type') {
206-
if (sourceExports.typeOnlyNamedExport == null) {
207-
// The export is a type export
208-
sourceExports.typeOnlyNamedExport = node;
209-
}
210-
} else if (sourceExports.valueOnlyNamedExport == null) {
206+
// The export is a type export
207+
sourceExports.typeOnlyNamedExport ??= node;
208+
} else {
211209
// The export is a value export
212-
sourceExports.valueOnlyNamedExport = node;
210+
sourceExports.valueOnlyNamedExport ??= node;
213211
}
214212

215213
// Next for the current export, we will separate type/value specifiers.

packages/eslint-plugin/src/rules/no-unsafe-return.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,7 @@ export default createRule({
8080
ts.isArrowFunction(functionTSNode)
8181
? getContextualType(checker, functionTSNode)
8282
: services.getTypeAtLocation(functionNode);
83-
if (!functionType) {
84-
functionType = services.getTypeAtLocation(functionNode);
85-
}
83+
functionType ??= services.getTypeAtLocation(functionNode);
8684
const callSignatures = tsutils.getCallSignaturesOfType(functionType);
8785
// If there is an explicit type annotation *and* that type matches the actual
8886
// function return type, we shouldn't complain (it's intentional, even if unsafe)

0 commit comments

Comments
 (0)