Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(isolated-declarations): report an error for parameters if they are ObjectPattern or ArrayPattern without an explicit type #3810

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions crates/oxc_isolated_declarations/src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,14 @@ impl<'a> IsolatedDeclarations<'a> {
&self,
param: &FormalParameter<'a>,
is_remaining_params_have_required: bool,
) -> FormalParameter<'a> {
let is_assignment_pattern = param.pattern.kind.is_assignment_pattern();
) -> Option<FormalParameter<'a>> {
let pattern = &param.pattern;
if pattern.type_annotation.is_none() && pattern.kind.is_destructuring_pattern() {
self.error(parameter_must_have_explicit_type(param.span));
return None;
}

let is_assignment_pattern = pattern.kind.is_assignment_pattern();
let mut pattern =
if let BindingPatternKind::AssignmentPattern(pattern) = &param.pattern.kind {
self.ast.copy(&pattern.left)
Expand Down Expand Up @@ -100,14 +106,14 @@ impl<'a> IsolatedDeclarations<'a> {
);
}

self.ast.formal_parameter(
Some(self.ast.formal_parameter(
param.span,
pattern,
None,
param.readonly,
false,
self.ast.new_vec(),
)
))
}

pub fn transform_formal_parameters(
Expand All @@ -118,14 +124,15 @@ impl<'a> IsolatedDeclarations<'a> {
return self.ast.alloc(self.ast.copy(params));
}

let items =
self.ast.new_vec_from_iter(params.items.iter().enumerate().map(|(index, item)| {
let items = self.ast.new_vec_from_iter(params.items.iter().enumerate().filter_map(
|(index, item)| {
let is_remaining_params_have_required =
params.items.iter().skip(index).any(|item| {
!(item.pattern.optional || item.pattern.kind.is_assignment_pattern())
});
self.transform_formal_parameter(item, is_remaining_params_have_required)
}));
},
));

if let Some(rest) = &params.rest {
if rest.argument.type_annotation.is_none() {
Expand Down
10 changes: 0 additions & 10 deletions crates/oxc_isolated_declarations/tests/deno.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,6 @@ export function foo(a: any): number {
}",
"export declare function foo(a?: string): number;",
);
// TODO: Isolated Declarations doesn't ObjectPattern
// transform_dts_test(
// "export function foo({a, b} = { a: 1, b: 2 }): number {
// return 2;
// }",
// "export declare function foo({ a, b }?: {
// a: number;
// b: number;
// }): number;",
// );
}

#[test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,23 @@
export function fnDeclGood(p: T = [], rParam = ""): void { };
export function fnDeclGood2(p: T = [], rParam?: number): void { };

export function fooGood([a, b]: any[] = [1, 2]): number {
return 2;
}

export const fooGood2 = ({a, b}: object = { a: 1, b: 2 }): number => {
return 2;
}

// Incorrect
export function fnDeclBad<T>(p: T = [], rParam: T = "", r2: T): void { }
export function fnDeclBad2<T>(p: T = [], r2: T): void { }
export function fnDeclBad3<T>(p: T = [], rParam?: T, r2: T): void { }

export function fooBad([a, b] = [1, 2]): number {
return 2;
}

export const fooBad2 = ({a, b} = { a: 1, b: 2 }): number => {
return 2;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,85 @@ input_file: crates/oxc_isolated_declarations/tests/fixtures/function-parameters.

export declare function fnDeclGood(p?: T, rParam?: string): void;
export declare function fnDeclGood2(p?: T, rParam?: number): void;
export declare function fooGood(): number;
export declare const fooGood2: () => number;
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;
export declare function fooBad(): number;
export declare const fooBad2: () => number;


==================== Errors ====================

x TS9011: Parameter must have an explicit type annotation with
| --isolatedDeclarations.
,-[5:25]
4 |
5 | export function fooGood([a, b]: any[] = [1, 2]): number {
: ^^^^^^^^^^^^^^^^^^^^^^
6 | return 2;
`----

x TS9011: Parameter must have an explicit type annotation with
| --isolatedDeclarations.
,-[9:26]
8 |
9 | export const fooGood2 = ({a, b}: object = { a: 1, b: 2 }): number => {
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
10 | return 2;
`----

x TS9025: Declaration emit for this parameter requires implicitly adding
| undefined to it's type. This is not supported with --isolatedDeclarations.
,-[6:30]
5 | // Incorrect
6 | export function fnDeclBad<T>(p: T = [], rParam: T = "", r2: T): void { }
: ^^^^^^^^^
7 | export function fnDeclBad2<T>(p: T = [], r2: T): void { }
`----
,-[14:30]
13 | // Incorrect
14 | export function fnDeclBad<T>(p: T = [], rParam: T = "", r2: T): void { }
: ^^^^^^^^^
15 | 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.
,-[6:41]
5 | // Incorrect
6 | export function fnDeclBad<T>(p: T = [], rParam: T = "", r2: T): void { }
: ^^^^^^^^^^^^^^
7 | export function fnDeclBad2<T>(p: T = [], r2: T): void { }
`----
,-[14:41]
13 | // Incorrect
14 | export function fnDeclBad<T>(p: T = [], rParam: T = "", r2: T): void { }
: ^^^^^^^^^^^^^^
15 | 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.
,-[7:31]
6 | export function fnDeclBad<T>(p: T = [], rParam: T = "", r2: T): void { }
7 | export function fnDeclBad2<T>(p: T = [], r2: T): void { }
: ^^^^^^^^^
8 | export function fnDeclBad3<T>(p: T = [], rParam?: T, r2: T): void { }
`----
,-[15:31]
14 | export function fnDeclBad<T>(p: T = [], rParam: T = "", r2: T): void { }
15 | export function fnDeclBad2<T>(p: T = [], r2: T): void { }
: ^^^^^^^^^
16 | 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.
,-[8:31]
7 | export function fnDeclBad2<T>(p: T = [], r2: T): void { }
8 | export function fnDeclBad3<T>(p: T = [], rParam?: T, r2: T): void { }
: ^^^^^^^^^
`----
,-[16:31]
15 | export function fnDeclBad2<T>(p: T = [], r2: T): void { }
16 | 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 => {
: ^^^^^^^^^^^^^^^^^^^^^^^
23 | return 2;
`----
Loading