Skip to content

Commit

Permalink
Add null to argument types of optional parameters (#4188)
Browse files Browse the repository at this point in the history
  • Loading branch information
RunDevelopment authored Dec 7, 2024
1 parent 720b9fe commit f931112
Show file tree
Hide file tree
Showing 15 changed files with 211 additions and 103 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
# `wasm-bindgen` Change Log
--------------------------------------------------------------------------------

## Unreleased

### Changed

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

--------------------------------------------------------------------------------

## [0.2.99](https://github.com/rustwasm/wasm-bindgen/compare/0.2.98...0.2.99)

Released 2024-12-07
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 @@ -1542,7 +1551,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 @@ -1564,8 +1584,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
72 changes: 36 additions & 36 deletions crates/cli/tests/reference/echo.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,42 +36,42 @@ export function echo_vec_uninit_i64(a: BigInt64Array): BigInt64Array;
export function echo_vec_string(a: (string)[]): (string)[];
export function echo_struct(a: Foo): Foo;
export function echo_vec_struct(a: (Foo)[]): (Foo)[];
export function echo_option_u8(a?: number): number | undefined;
export function echo_option_i8(a?: number): number | undefined;
export function echo_option_u16(a?: number): number | undefined;
export function echo_option_i16(a?: number): number | undefined;
export function echo_option_u32(a?: number): number | undefined;
export function echo_option_i32(a?: number): number | undefined;
export function echo_option_u64(a?: bigint): bigint | undefined;
export function echo_option_i64(a?: bigint): bigint | undefined;
export function echo_option_u128(a?: bigint): bigint | undefined;
export function echo_option_i128(a?: bigint): bigint | undefined;
export function echo_option_usize(a?: number): number | undefined;
export function echo_option_isize(a?: number): number | undefined;
export function echo_option_f32(a?: number): number | undefined;
export function echo_option_f64(a?: number): number | undefined;
export function echo_option_bool(a?: boolean): boolean | undefined;
export function echo_option_char(a?: string): string | undefined;
export function echo_option_string(a?: string): string | undefined;
export function echo_option_vec_u8(a?: Uint8Array): Uint8Array | undefined;
export function echo_option_vec_i8(a?: Int8Array): Int8Array | undefined;
export function echo_option_vec_u16(a?: Uint16Array): Uint16Array | undefined;
export function echo_option_vec_i16(a?: Int16Array): Int16Array | undefined;
export function echo_option_vec_u32(a?: Uint32Array): Uint32Array | undefined;
export function echo_option_vec_i32(a?: Int32Array): Int32Array | undefined;
export function echo_option_vec_u64(a?: BigUint64Array): BigUint64Array | undefined;
export function echo_option_vec_i64(a?: BigInt64Array): BigInt64Array | undefined;
export function echo_option_vec_uninit_u8(a?: Uint8Array): Uint8Array | undefined;
export function echo_option_vec_uninit_i8(a?: Int8Array): Int8Array | undefined;
export function echo_option_vec_uninit_u16(a?: Uint16Array): Uint16Array | undefined;
export function echo_option_vec_uninit_i16(a?: Int16Array): Int16Array | undefined;
export function echo_option_vec_uninit_u32(a?: Uint32Array): Uint32Array | undefined;
export function echo_option_vec_uninit_i32(a?: Int32Array): Int32Array | undefined;
export function echo_option_vec_uninit_u64(a?: BigUint64Array): BigUint64Array | undefined;
export function echo_option_vec_uninit_i64(a?: BigInt64Array): BigInt64Array | undefined;
export function echo_option_vec_string(a?: (string)[]): (string)[] | undefined;
export function echo_option_struct(a?: Foo): Foo | undefined;
export function echo_option_vec_struct(a?: (Foo)[]): (Foo)[] | undefined;
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_u128(a?: bigint | null): bigint | undefined;
export function echo_option_i128(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_vec_i8(a?: Int8Array | null): Int8Array | undefined;
export function echo_option_vec_u16(a?: Uint16Array | null): Uint16Array | undefined;
export function echo_option_vec_i16(a?: Int16Array | null): Int16Array | undefined;
export function echo_option_vec_u32(a?: Uint32Array | null): Uint32Array | undefined;
export function echo_option_vec_i32(a?: Int32Array | null): Int32Array | undefined;
export function echo_option_vec_u64(a?: BigUint64Array | null): BigUint64Array | undefined;
export function echo_option_vec_i64(a?: BigInt64Array | null): BigInt64Array | undefined;
export function echo_option_vec_uninit_u8(a?: Uint8Array | null): Uint8Array | undefined;
export function echo_option_vec_uninit_i8(a?: Int8Array | null): Int8Array | undefined;
export function echo_option_vec_uninit_u16(a?: Uint16Array | null): Uint16Array | undefined;
export function echo_option_vec_uninit_i16(a?: Int16Array | null): Int16Array | undefined;
export function echo_option_vec_uninit_u32(a?: Uint32Array | null): Uint32Array | undefined;
export function echo_option_vec_uninit_i32(a?: Int32Array | null): Int32Array | undefined;
export function echo_option_vec_uninit_u64(a?: BigUint64Array | null): BigUint64Array | undefined;
export function echo_option_vec_uninit_i64(a?: BigInt64Array | null): BigInt64Array | undefined;
export function echo_option_vec_string(a?: (string)[] | null): (string)[] | 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 {
private constructor();
free(): void;
Expand Down
Loading

0 comments on commit f931112

Please sign in to comment.