diff --git a/CHANGELOG.md b/CHANGELOG.md index 9229d4b292c..777d4f60031 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -96,6 +96,9 @@ * Fixed imports for functions using `this` and late binding. [#4225](https://github.com/rustwasm/wasm-bindgen/pull/4225) +* Don't expose non-functioning implicit constructors to classes when none are provided. + [#4282](https://github.com/rustwasm/wasm-bindgen/pull/4282) + -------------------------------------------------------------------------------- ## [0.2.95](https://github.com/rustwasm/wasm-bindgen/compare/0.2.94...0.2.95) diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index aff91c6cfcc..babbfc09d93 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -1016,14 +1016,19 @@ __wbg_set_wasm(wasm);" let mut dst = format!("class {} {{\n", name); let mut ts_dst = format!("export {}", dst); - if self.config.debug && !class.has_constructor { - dst.push_str( - " - constructor() { - throw new Error('cannot invoke `new` directly'); - } - ", - ); + if !class.has_constructor { + // declare the constructor as private to prevent direct instantiation + ts_dst.push_str(" private constructor();\n"); + + if self.config.debug { + dst.push_str( + " + constructor() { + throw new Error('cannot invoke `new` directly'); + } + ", + ); + } } if class.wrap_needed { diff --git a/crates/cli/tests/reference/builder.d.ts b/crates/cli/tests/reference/builder.d.ts index 032da9dcf73..5a2da02112d 100644 --- a/crates/cli/tests/reference/builder.d.ts +++ b/crates/cli/tests/reference/builder.d.ts @@ -1,6 +1,7 @@ /* tslint:disable */ /* eslint-disable */ export class ClassBuilder { + private constructor(); free(): void; static builder(): ClassBuilder; } diff --git a/crates/cli/tests/reference/echo.d.ts b/crates/cli/tests/reference/echo.d.ts index d5b187aa985..7f72b5e2d34 100644 --- a/crates/cli/tests/reference/echo.d.ts +++ b/crates/cli/tests/reference/echo.d.ts @@ -57,5 +57,6 @@ 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 class Foo { + private constructor(); free(): void; } diff --git a/crates/cli/tests/reference/getter-setter.d.ts b/crates/cli/tests/reference/getter-setter.d.ts index 4c207c3c7e6..8222ca2a462 100644 --- a/crates/cli/tests/reference/getter-setter.d.ts +++ b/crates/cli/tests/reference/getter-setter.d.ts @@ -1,6 +1,7 @@ /* tslint:disable */ /* eslint-disable */ export class Foo { + private constructor(); free(): void; x: number; y?: number; diff --git a/crates/cli/tests/reference/raw.d.ts b/crates/cli/tests/reference/raw.d.ts index 6dc3f5c628f..b28681c178f 100644 --- a/crates/cli/tests/reference/raw.d.ts +++ b/crates/cli/tests/reference/raw.d.ts @@ -2,6 +2,7 @@ /* eslint-disable */ export function test1(test: number): number; export class Test { + private constructor(); free(): void; static test1(test: number): Test; test2(test: number): void; diff --git a/crates/typescript-tests/src/custom_section.rs b/crates/typescript-tests/src/custom_section.rs index 4ed757c35ca..294cc9f5b25 100644 --- a/crates/typescript-tests/src/custom_section.rs +++ b/crates/typescript-tests/src/custom_section.rs @@ -17,3 +17,11 @@ const _: &str = TS_INTERFACE_EXPORT2; pub struct Person { pub height: u32, } + +#[wasm_bindgen] +impl Person { + #[wasm_bindgen(constructor)] + pub fn new() -> Self { + Self { height: 170 } + } +} diff --git a/crates/typescript-tests/src/getters_setters.rs b/crates/typescript-tests/src/getters_setters.rs index b5534fc0111..7bc14119199 100644 --- a/crates/typescript-tests/src/getters_setters.rs +++ b/crates/typescript-tests/src/getters_setters.rs @@ -10,6 +10,16 @@ pub struct ColorWithGetters { #[wasm_bindgen] impl ColorWithGetters { + #[wasm_bindgen(constructor)] + pub fn new() -> Self { + Self { + r: 0.0, + _g: 0.0, + _b: 0.0, + _a: 0, + } + } + #[wasm_bindgen(getter)] pub fn r(&self) -> f64 { self.r @@ -31,6 +41,16 @@ pub struct ColorWithSetters { #[wasm_bindgen] impl ColorWithSetters { + #[wasm_bindgen(constructor)] + pub fn new() -> Self { + Self { + r: 0.0, + _g: 0.0, + _b: 0.0, + a: 0, + } + } + #[wasm_bindgen(setter)] pub fn set_r(&mut self, r: f64) { self.r = r; @@ -57,6 +77,16 @@ pub struct ColorWithGetterAndSetter { #[wasm_bindgen] impl ColorWithGetterAndSetter { + #[wasm_bindgen(constructor)] + pub fn new() -> Self { + Self { + r: 0.0, + _g: 0.0, + _b: 0.0, + a: 0, + } + } + #[wasm_bindgen(getter)] pub fn r(&self) -> f64 { self.r