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

Add null to argument types of optional parameters #4188

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c1d8bc6
Add `null` to argument types of optional parameters
RunDevelopment Oct 12, 2024
0fe90f9
Update echo.js
RunDevelopment Oct 12, 2024
e3fd6f0
Merge branch 'main' into input-null
RunDevelopment Oct 12, 2024
ff5dd9d
Updated refs and changelog
RunDevelopment Oct 12, 2024
914222d
Adjust changelog entry
daxpedda Oct 12, 2024
49c13bf
Merge branch 'main' into input-null
RunDevelopment Oct 12, 2024
3febb5e
Fixed missing null in TS optional args
RunDevelopment Oct 12, 2024
841f802
Remove `| undefined` from JSDoc types
RunDevelopment Oct 13, 2024
22e345f
Merge branch 'main' into input-null
RunDevelopment Oct 13, 2024
bf08a5d
Merge branch 'main' into input-null
RunDevelopment Oct 15, 2024
90f1efb
Update ref
RunDevelopment Oct 15, 2024
7695674
Merge branch 'main' into input-null
RunDevelopment Oct 15, 2024
e86acdf
Merge branch 'main' into input-null
RunDevelopment Oct 16, 2024
b712add
Updated refs
RunDevelopment Oct 16, 2024
e9cedd4
Update crates/cli-support/src/js/binding.rs
RunDevelopment Oct 17, 2024
b23e3d7
Merge branch 'main' into input-null
RunDevelopment Oct 29, 2024
fd337f2
Updated refs
RunDevelopment Oct 29, 2024
3939d03
Merge branch 'main' into input-null
RunDevelopment Oct 31, 2024
d4ff7fa
Updated refs
RunDevelopment Oct 31, 2024
b45cfb6
Unreachable has been reached
RunDevelopment Oct 31, 2024
dd79ed4
Fixed TS test
RunDevelopment Oct 31, 2024
54b6852
Added test for optional args
RunDevelopment Oct 31, 2024
d329619
Merge branch 'main' into input-null
RunDevelopment Nov 30, 2024
36846b3
Updated refs
RunDevelopment Nov 30, 2024
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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
* Deprecate `--reference-types` in favor of automatic target feature detection.
[#4237](https://github.com/rustwasm/wasm-bindgen/pull/4237)

* Optional parameters are now typed as `T | undefined | null` to reflect the actual JS behavior.
daxpedda marked this conversation as resolved.
Show resolved Hide resolved
[#4188](https://github.com/rustwasm/wasm-bindgen/pull/4188)

### Fixed

* Fixed methods with `self: &Self` consuming the object.
Expand Down
43 changes: 33 additions & 10 deletions crates/cli-support/src/js/binding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,13 +321,15 @@ impl<'a, 'b> Builder<'a, 'b> {
let mut ts = String::new();
match ty {
AdapterType::Option(ty) if omittable => {
// e.g. `foo?: string | null`
arg.push_str("?: ");
adapter2ts(ty, &mut ts, Some(&mut ts_refs));
adapter2ts(ty, TypePosition::Argument, &mut ts, Some(&mut ts_refs));
ts.push_str(" | null");
}
ty => {
omittable = false;
arg.push_str(": ");
adapter2ts(ty, &mut ts, Some(&mut ts_refs));
adapter2ts(ty, TypePosition::Argument, &mut ts, Some(&mut ts_refs));
}
}
arg.push_str(&ts);
Expand Down Expand Up @@ -363,7 +365,12 @@ impl<'a, 'b> Builder<'a, 'b> {
let mut ret = String::new();
match result_tys.len() {
0 => ret.push_str("void"),
1 => adapter2ts(&result_tys[0], &mut ret, Some(&mut ts_refs)),
1 => adapter2ts(
&result_tys[0],
TypePosition::Return,
&mut ret,
Some(&mut ts_refs),
),
_ => ret.push_str("[any]"),
}
if asyncness {
Expand Down Expand Up @@ -395,16 +402,18 @@ impl<'a, 'b> Builder<'a, 'b> {
for (name, ty) in fn_arg_names.iter().zip(arg_tys).rev() {
let mut arg = "@param {".to_string();

adapter2ts(ty, &mut arg, None);
arg.push_str("} ");
match ty {
AdapterType::Option(..) if omittable => {
AdapterType::Option(ty) if omittable => {
adapter2ts(ty, TypePosition::Argument, &mut arg, None);
arg.push_str(" | null} ");
arg.push('[');
arg.push_str(name);
arg.push(']');
}
_ => {
omittable = false;
adapter2ts(ty, TypePosition::Argument, &mut arg, None);
arg.push_str("} ");
arg.push_str(name);
}
}
Expand All @@ -416,7 +425,7 @@ impl<'a, 'b> Builder<'a, 'b> {

if let (Some(name), Some(ty)) = (variadic_arg, arg_tys.last()) {
ret.push_str("@param {...");
adapter2ts(ty, &mut ret, None);
adapter2ts(ty, TypePosition::Argument, &mut ret, None);
ret.push_str("} ");
ret.push_str(name);
ret.push('\n');
Expand Down Expand Up @@ -1488,7 +1497,18 @@ impl Invocation {
}
}

fn adapter2ts(ty: &AdapterType, dst: &mut String, refs: Option<&mut HashSet<TsReference>>) {
#[derive(Debug, Clone, Copy)]
enum TypePosition {
Argument,
Return,
}

fn adapter2ts(
ty: &AdapterType,
position: TypePosition,
dst: &mut String,
refs: Option<&mut HashSet<TsReference>>,
) {
match ty {
AdapterType::I32
| AdapterType::S8
Expand All @@ -1506,8 +1526,11 @@ fn adapter2ts(ty: &AdapterType, dst: &mut String, refs: Option<&mut HashSet<TsRe
AdapterType::Bool => dst.push_str("boolean"),
AdapterType::Vector(kind) => dst.push_str(&kind.js_ty()),
AdapterType::Option(ty) => {
adapter2ts(ty, dst, refs);
dst.push_str(" | undefined");
adapter2ts(ty, position, dst, refs);
dst.push_str(match position {
TypePosition::Argument => " | null | undefined",
TypePosition::Return => " | undefined",
});
}
AdapterType::NamedExternref(name) => dst.push_str(name),
AdapterType::Struct(name) => dst.push_str(name),
Expand Down
41 changes: 41 additions & 0 deletions crates/cli/tests/reference/echo.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* tslint:disable */
/* eslint-disable */
export function echo_u8(a: number): number;
export function echo_i8(a: number): number;
export function echo_u16(a: number): number;
export function echo_i16(a: number): number;
export function echo_u32(a: number): number;
export function echo_i32(a: number): number;
export function echo_u64(a: bigint): bigint;
export function echo_i64(a: bigint): bigint;
export function echo_usize(a: number): number;
export function echo_isize(a: number): number;
export function echo_f32(a: number): number;
export function echo_f64(a: number): number;
export function echo_bool(a: boolean): boolean;
export function echo_char(a: string): string;
export function echo_string(a: string): string;
export function echo_vec_u8(a: Uint8Array): Uint8Array;
export function echo_struct(a: Foo): Foo;
export function echo_vec_struct(a: (Foo)[]): (Foo)[];
export function echo_option_u8(a?: number | null): number | undefined;
export function echo_option_i8(a?: number | null): number | undefined;
export function echo_option_u16(a?: number | null): number | undefined;
export function echo_option_i16(a?: number | null): number | undefined;
export function echo_option_u32(a?: number | null): number | undefined;
export function echo_option_i32(a?: number | null): number | undefined;
export function echo_option_u64(a?: bigint | null): bigint | undefined;
export function echo_option_i64(a?: bigint | null): bigint | undefined;
export function echo_option_usize(a?: number | null): number | undefined;
export function echo_option_isize(a?: number | null): number | undefined;
export function echo_option_f32(a?: number | null): number | undefined;
export function echo_option_f64(a?: number | null): number | undefined;
export function echo_option_bool(a?: boolean | null): boolean | undefined;
export function echo_option_char(a?: string | null): string | undefined;
export function echo_option_string(a?: string | null): string | undefined;
export function echo_option_vec_u8(a?: Uint8Array | null): Uint8Array | undefined;
export function echo_option_struct(a?: Foo | null): Foo | undefined;
export function echo_option_vec_struct(a?: (Foo)[] | null): (Foo)[] | undefined;
export class Foo {
free(): void;
}
Loading