mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
feat(isolated-declarations): treat AssignmentPattern as optional (#3748)
This commit is contained in:
parent
887da40518
commit
9ea30c41ff
8 changed files with 88 additions and 21 deletions
|
|
@ -41,7 +41,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
|||
pub fn transform_formal_parameter(
|
||||
&self,
|
||||
param: &FormalParameter<'a>,
|
||||
next_param: Option<&FormalParameter<'a>>,
|
||||
is_remaining_params_have_required: bool,
|
||||
) -> FormalParameter<'a> {
|
||||
let is_assignment_pattern = param.pattern.kind.is_assignment_pattern();
|
||||
let mut pattern =
|
||||
|
|
@ -52,9 +52,6 @@ impl<'a> IsolatedDeclarations<'a> {
|
|||
};
|
||||
|
||||
if is_assignment_pattern || pattern.type_annotation.is_none() {
|
||||
let is_next_param_optional =
|
||||
next_param.map_or(true, |next_param| next_param.pattern.optional);
|
||||
|
||||
let type_annotation = pattern
|
||||
.type_annotation
|
||||
.as_ref()
|
||||
|
|
@ -70,7 +67,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
|||
.map(|ts_type| {
|
||||
// jf next param is not optional and current param is assignment pattern
|
||||
// we need to add undefined to it's type
|
||||
if !is_next_param_optional {
|
||||
if is_remaining_params_have_required {
|
||||
if matches!(ts_type, TSType::TSTypeReference(_)) {
|
||||
self.error(implicitly_adding_undefined_to_type(param.span));
|
||||
} else if !ts_type.is_maybe_undefined() {
|
||||
|
|
@ -95,7 +92,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
|||
self.ast.copy(&pattern.kind),
|
||||
type_annotation,
|
||||
// if it's assignment pattern, it's optional
|
||||
pattern.optional || (is_next_param_optional && is_assignment_pattern),
|
||||
pattern.optional || (!is_remaining_params_have_required && is_assignment_pattern),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -119,7 +116,11 @@ impl<'a> IsolatedDeclarations<'a> {
|
|||
|
||||
let items =
|
||||
self.ast.new_vec_from_iter(params.items.iter().enumerate().map(|(index, item)| {
|
||||
self.transform_formal_parameter(item, params.items.get(index + 1))
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
class B {}
|
||||
8
crates/oxc_isolated_declarations/tests/fixtures/function-parameters.ts
vendored
Normal file
8
crates/oxc_isolated_declarations/tests/fixtures/function-parameters.ts
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
// Correct
|
||||
export function fnDeclGood(p: T = [], rParam = ""): void { };
|
||||
export function fnDeclGood2(p: T = [], rParam?: number): void { };
|
||||
|
||||
// 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 { }
|
||||
|
|
@ -1 +0,0 @@
|
|||
class A {}
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
use std::{fs, path::Path};
|
||||
use std::{fs, path::Path, sync::Arc};
|
||||
|
||||
use oxc_allocator::Allocator;
|
||||
use oxc_codegen::CodeGenerator;
|
||||
use oxc_isolated_declarations::IsolatedDeclarations;
|
||||
use oxc_parser::Parser;
|
||||
use oxc_span::SourceType;
|
||||
|
||||
|
|
@ -9,7 +10,27 @@ fn transform(path: &Path, source_text: &str) -> String {
|
|||
let allocator = Allocator::default();
|
||||
let source_type = SourceType::from_path(path).unwrap();
|
||||
let program = Parser::new(&allocator, source_text, source_type).parse().program;
|
||||
CodeGenerator::new().build(&program).source_text
|
||||
|
||||
let ret = IsolatedDeclarations::new(&allocator).build(&program);
|
||||
let code = CodeGenerator::new().build(&ret.program).source_text;
|
||||
|
||||
let mut snapshot = format!("==================== .D.TS ====================\n\n{code}\n\n");
|
||||
if !ret.errors.is_empty() {
|
||||
let source = Arc::new(source_text.to_string());
|
||||
let error_messages = ret
|
||||
.errors
|
||||
.iter()
|
||||
.map(|d| d.clone().with_source_code(Arc::clone(&source)))
|
||||
.map(|error| format!("{error:?}"))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
snapshot.push_str(&format!(
|
||||
"==================== Errors ====================\n\n{error_messages}\n\n"
|
||||
));
|
||||
}
|
||||
|
||||
snapshot
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
source: crates/oxc_isolated_declarations/tests/mod.rs
|
||||
input_file: crates/oxc_isolated_declarations/tests/fixtures/complex.ts
|
||||
---
|
||||
class B {}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
---
|
||||
source: crates/oxc_isolated_declarations/tests/mod.rs
|
||||
input_file: crates/oxc_isolated_declarations/tests/fixtures/function-parameters.ts
|
||||
---
|
||||
==================== .D.TS ====================
|
||||
|
||||
export declare function fnDeclGood(p?: T, rParam?: string): void;
|
||||
export declare function fnDeclGood2(p?: T, rParam?: number): 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;
|
||||
|
||||
|
||||
==================== Errors ====================
|
||||
|
||||
x 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 { }
|
||||
`----
|
||||
|
||||
x 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 { }
|
||||
`----
|
||||
|
||||
x 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 { }
|
||||
`----
|
||||
|
||||
x 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 { }
|
||||
: ^^^^^^^^^
|
||||
`----
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
source: crates/oxc_isolated_declarations/tests/mod.rs
|
||||
input_file: crates/oxc_isolated_declarations/tests/fixtures/simple.ts
|
||||
---
|
||||
class A {}
|
||||
Loading…
Reference in a new issue