mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
fix(isolated_declarations): Remove nested AssignmentPatterns from inside parameters (#4077)
The default values in destructured parameters are retained in
declarations, which can cause captured variables to be part of the emit
when they shouldn't be. This can also lead to unnecessary isolated
declaration errors when those variables are themselves missing type
annotations and can't be inferred.
For example:
```ts
const x = 42;
const y = '';
export function fooGood3({a = x, b: [{c = y}]}: object): void {}
```
before this change will be emitted as:
```ts
declare const x = 42;
declare const y = '';
export declare function fooGood3({ a = x, b: [{ c = y }] }: object): void;
```
and after this change will be emitted as:
```ts
export declare function fooGood3({ a, b: [{ c }] }: object): void;
```
Co-authored-by: MichaelMitchell-at <=>
This commit is contained in:
parent
51eb8fe46c
commit
3fcad5e16f
5 changed files with 65 additions and 32 deletions
|
|
@ -0,0 +1,24 @@
|
|||
use oxc_ast::{
|
||||
ast::BindingPatternKind, visit::walk_mut::walk_binding_pattern_kind, AstBuilder, VisitMut,
|
||||
};
|
||||
|
||||
pub struct FormalParameterBindingPattern<'a> {
|
||||
ast: AstBuilder<'a>,
|
||||
}
|
||||
|
||||
impl<'a> VisitMut<'a> for FormalParameterBindingPattern<'a> {
|
||||
fn visit_binding_pattern_kind(&mut self, kind: &mut BindingPatternKind<'a>) {
|
||||
if let BindingPatternKind::AssignmentPattern(assignment) = kind {
|
||||
*kind = self.ast.copy(&assignment.left.kind);
|
||||
}
|
||||
|
||||
walk_binding_pattern_kind(self, kind);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FormalParameterBindingPattern<'a> {
|
||||
pub fn remove_assignments_from_kind(ast: AstBuilder<'a>, kind: &mut BindingPatternKind<'a>) {
|
||||
let mut visitor = FormalParameterBindingPattern { ast };
|
||||
visitor.visit_binding_pattern_kind(kind);
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ use crate::{
|
|||
function_must_have_explicit_return_type, implicitly_adding_undefined_to_type,
|
||||
parameter_must_have_explicit_type,
|
||||
},
|
||||
formal_parameter_binding_pattern::FormalParameterBindingPattern,
|
||||
IsolatedDeclarations,
|
||||
};
|
||||
|
||||
|
|
@ -65,6 +66,8 @@ impl<'a> IsolatedDeclarations<'a> {
|
|||
self.ast.copy(¶m.pattern)
|
||||
};
|
||||
|
||||
FormalParameterBindingPattern::remove_assignments_from_kind(self.ast, &mut pattern.kind);
|
||||
|
||||
if is_assignment_pattern || pattern.type_annotation.is_none() {
|
||||
let type_annotation = pattern
|
||||
.type_annotation
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ mod class;
|
|||
mod declaration;
|
||||
mod diagnostics;
|
||||
mod r#enum;
|
||||
mod formal_parameter_binding_pattern;
|
||||
mod function;
|
||||
mod inferrer;
|
||||
mod literal;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@ export const fooGood2 = ({a, b}: object = { a: 1, b: 2 }): number => {
|
|||
return 2;
|
||||
}
|
||||
|
||||
const x = 42;
|
||||
const y = '';
|
||||
export function fooGood3({a = x, b: [{c = y}]}: object): void {}
|
||||
|
||||
// Incorrect
|
||||
export function fnDeclBad<T>(p: T = [], rParam: T = "", r2: T): void { }
|
||||
export function fnDeclBad2<T>(p: T = [], r2: T): void { }
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ export declare function fnDeclGood(p?: T, rParam?: string): void;
|
|||
export declare function fnDeclGood2(p?: T, rParam?: number): void;
|
||||
export declare function fooGood([a, b]?: any[]): number;
|
||||
export declare const fooGood2: ({ a, b }?: object) => number;
|
||||
export declare function fooGood3({ a, b: [{ c }] }: object): void;
|
||||
export declare function fnDeclBad<T>(p: T, rParam: T, r2: T): void;
|
||||
export declare function fnDeclBad2<T>(p: T, r2: T): void;
|
||||
export declare function fnDeclBad3<T>(p: T, rParam?: T, r2: T): void;
|
||||
|
|
@ -19,54 +20,54 @@ export declare const fooBad2: () => number;
|
|||
|
||||
x TS9025: Declaration emit for this parameter requires implicitly adding
|
||||
| undefined to it's type. This is not supported with --isolatedDeclarations.
|
||||
,-[14:30]
|
||||
13 | // Incorrect
|
||||
14 | export function fnDeclBad<T>(p: T = [], rParam: T = "", r2: T): void { }
|
||||
,-[18:30]
|
||||
17 | // Incorrect
|
||||
18 | export function fnDeclBad<T>(p: T = [], rParam: T = "", r2: T): void { }
|
||||
: ^^^^^^^^^
|
||||
15 | export function fnDeclBad2<T>(p: T = [], r2: T): void { }
|
||||
19 | export function fnDeclBad2<T>(p: T = [], r2: T): void { }
|
||||
`----
|
||||
|
||||
x TS9025: Declaration emit for this parameter requires implicitly adding
|
||||
| undefined to it's type. This is not supported with --isolatedDeclarations.
|
||||
,-[14:41]
|
||||
13 | // Incorrect
|
||||
14 | export function fnDeclBad<T>(p: T = [], rParam: T = "", r2: T): void { }
|
||||
,-[18:41]
|
||||
17 | // Incorrect
|
||||
18 | export function fnDeclBad<T>(p: T = [], rParam: T = "", r2: T): void { }
|
||||
: ^^^^^^^^^^^^^^
|
||||
15 | export function fnDeclBad2<T>(p: T = [], r2: T): void { }
|
||||
19 | export function fnDeclBad2<T>(p: T = [], r2: T): void { }
|
||||
`----
|
||||
|
||||
x TS9025: Declaration emit for this parameter requires implicitly adding
|
||||
| undefined to it's type. This is not supported with --isolatedDeclarations.
|
||||
,-[15:31]
|
||||
14 | export function fnDeclBad<T>(p: T = [], rParam: T = "", r2: T): void { }
|
||||
15 | export function fnDeclBad2<T>(p: T = [], r2: T): void { }
|
||||
,-[19:31]
|
||||
18 | export function fnDeclBad<T>(p: T = [], rParam: T = "", r2: T): void { }
|
||||
19 | export function fnDeclBad2<T>(p: T = [], r2: T): void { }
|
||||
: ^^^^^^^^^
|
||||
16 | export function fnDeclBad3<T>(p: T = [], rParam?: T, r2: T): void { }
|
||||
20 | export function fnDeclBad3<T>(p: T = [], rParam?: T, r2: T): void { }
|
||||
`----
|
||||
|
||||
x TS9025: Declaration emit for this parameter requires implicitly adding
|
||||
| undefined to it's type. This is not supported with --isolatedDeclarations.
|
||||
,-[16:31]
|
||||
15 | export function fnDeclBad2<T>(p: T = [], r2: T): void { }
|
||||
16 | export function fnDeclBad3<T>(p: T = [], rParam?: T, r2: T): void { }
|
||||
,-[20:31]
|
||||
19 | export function fnDeclBad2<T>(p: T = [], r2: T): void { }
|
||||
20 | export function fnDeclBad3<T>(p: T = [], rParam?: T, r2: T): void { }
|
||||
: ^^^^^^^^^
|
||||
17 |
|
||||
`----
|
||||
|
||||
x TS9011: Parameter must have an explicit type annotation with
|
||||
| --isolatedDeclarations.
|
||||
,-[18:24]
|
||||
17 |
|
||||
18 | export function fooBad([a, b] = [1, 2]): number {
|
||||
: ^^^^^^^^^^^^^^^
|
||||
19 | return 2;
|
||||
`----
|
||||
|
||||
x TS9011: Parameter must have an explicit type annotation with
|
||||
| --isolatedDeclarations.
|
||||
,-[22:25]
|
||||
21 |
|
||||
22 | export const fooBad2 = ({a, b} = { a: 1, b: 2 }): number => {
|
||||
: ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
`----
|
||||
|
||||
x TS9011: Parameter must have an explicit type annotation with
|
||||
| --isolatedDeclarations.
|
||||
,-[22:24]
|
||||
21 |
|
||||
22 | export function fooBad([a, b] = [1, 2]): number {
|
||||
: ^^^^^^^^^^^^^^^
|
||||
23 | return 2;
|
||||
`----
|
||||
|
||||
x TS9011: Parameter must have an explicit type annotation with
|
||||
| --isolatedDeclarations.
|
||||
,-[26:25]
|
||||
25 |
|
||||
26 | export const fooBad2 = ({a, b} = { a: 1, b: 2 }): number => {
|
||||
: ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
27 | return 2;
|
||||
`----
|
||||
|
|
|
|||
Loading…
Reference in a new issue