diff --git a/crates/oxc_isolated_declarations/src/function.rs b/crates/oxc_isolated_declarations/src/function.rs index ab6dbf0940a30..389ffa959bbc8 100644 --- a/crates/oxc_isolated_declarations/src/function.rs +++ b/crates/oxc_isolated_declarations/src/function.rs @@ -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> { + let pattern = ¶m.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) = ¶m.pattern.kind { self.ast.copy(&pattern.left) @@ -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( @@ -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) = ¶ms.rest { if rest.argument.type_annotation.is_none() { diff --git a/crates/oxc_isolated_declarations/tests/deno.rs b/crates/oxc_isolated_declarations/tests/deno.rs index e371e28f61d72..f471f6e03f64d 100644 --- a/crates/oxc_isolated_declarations/tests/deno.rs +++ b/crates/oxc_isolated_declarations/tests/deno.rs @@ -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] diff --git a/crates/oxc_isolated_declarations/tests/fixtures/function-parameters.ts b/crates/oxc_isolated_declarations/tests/fixtures/function-parameters.ts index 7c68b8aebc0d7..b43e3dfcb3881 100644 --- a/crates/oxc_isolated_declarations/tests/fixtures/function-parameters.ts +++ b/crates/oxc_isolated_declarations/tests/fixtures/function-parameters.ts @@ -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(p: T = [], rParam: T = "", r2: T): void { } export function fnDeclBad2(p: T = [], r2: T): void { } export function fnDeclBad3(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; +} \ No newline at end of file diff --git a/crates/oxc_isolated_declarations/tests/snapshots/function-parameters.snap b/crates/oxc_isolated_declarations/tests/snapshots/function-parameters.snap index aae53ee93da73..1efd93ab35f56 100644 --- a/crates/oxc_isolated_declarations/tests/snapshots/function-parameters.snap +++ b/crates/oxc_isolated_declarations/tests/snapshots/function-parameters.snap @@ -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(p: T, rParam: T, r2: T): void; export declare function fnDeclBad2(p: T, r2: T): void; export declare function fnDeclBad3(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(p: T = [], rParam: T = "", r2: T): void { } - : ^^^^^^^^^ - 7 | export function fnDeclBad2(p: T = [], r2: T): void { } - `---- + ,-[14:30] + 13 | // Incorrect + 14 | export function fnDeclBad(p: T = [], rParam: T = "", r2: T): void { } + : ^^^^^^^^^ + 15 | export function fnDeclBad2(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(p: T = [], rParam: T = "", r2: T): void { } - : ^^^^^^^^^^^^^^ - 7 | export function fnDeclBad2(p: T = [], r2: T): void { } - `---- + ,-[14:41] + 13 | // Incorrect + 14 | export function fnDeclBad(p: T = [], rParam: T = "", r2: T): void { } + : ^^^^^^^^^^^^^^ + 15 | export function fnDeclBad2(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(p: T = [], rParam: T = "", r2: T): void { } - 7 | export function fnDeclBad2(p: T = [], r2: T): void { } - : ^^^^^^^^^ - 8 | export function fnDeclBad3(p: T = [], rParam?: T, r2: T): void { } - `---- + ,-[15:31] + 14 | export function fnDeclBad(p: T = [], rParam: T = "", r2: T): void { } + 15 | export function fnDeclBad2(p: T = [], r2: T): void { } + : ^^^^^^^^^ + 16 | export function fnDeclBad3(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(p: T = [], r2: T): void { } - 8 | export function fnDeclBad3(p: T = [], rParam?: T, r2: T): void { } - : ^^^^^^^^^ - `---- + ,-[16:31] + 15 | export function fnDeclBad2(p: T = [], r2: T): void { } + 16 | export function fnDeclBad3(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; + `----