Skip to content

Commit d193b2d

Browse files
committed
Improving the TypeScript types for the init function
1 parent db8d3e4 commit d193b2d

File tree

2 files changed

+66
-9
lines changed

2 files changed

+66
-9
lines changed

crates/cli-support/src/js/mod.rs

+17-9
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,9 @@ impl<'a> Context<'a> {
461461
Ok(imports)
462462
}
463463

464-
fn ts_for_init_fn(has_memory: bool, has_module_or_path_optional: bool) -> String {
464+
fn ts_for_init_fn(&self, has_memory: bool, has_module_or_path_optional: bool) -> Result<String, Error> {
465+
let output = crate::wasm2es6js::interface(&self.module)?;
466+
465467
let (memory_doc, memory_param) = if has_memory {
466468
(
467469
"* @param {WebAssembly.Memory} maybe_memory\n",
@@ -471,22 +473,28 @@ impl<'a> Context<'a> {
471473
("", "")
472474
};
473475
let arg_optional = if has_module_or_path_optional { "?" } else { "" };
474-
format!(
476+
Ok(format!(
475477
"\n\
478+
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;\n\
479+
\n\
480+
export interface InitOutput {{\n\
481+
{output}}}\n\
482+
\n\
476483
/**\n\
477-
* If `module_or_path` is {{RequestInfo}}, makes a request and\n\
484+
* If `module_or_path` is {{RequestInfo}} or {{URL}}, makes a request and\n\
478485
* for everything else, calls `WebAssembly.instantiate` directly.\n\
479486
*\n\
480-
* @param {{RequestInfo | BufferSource | WebAssembly.Module}} module_or_path\n\
487+
* @param {{InitInput | Promise<InitInput>}} module_or_path\n\
481488
{}\
482489
*\n\
483-
* @returns {{Promise<any>}}\n\
490+
* @returns {{Promise<InitOutput>}}\n\
484491
*/\n\
485492
export default function init \
486-
(module_or_path{}: RequestInfo | BufferSource | WebAssembly.Module{}): Promise<any>;
493+
(module_or_path{}: InitInput | Promise<InitInput>{}): Promise<InitOutput>;
487494
",
488-
memory_doc, arg_optional, memory_param
489-
)
495+
memory_doc, arg_optional, memory_param,
496+
output = output,
497+
))
490498
}
491499

492500
fn gen_init(
@@ -541,7 +549,7 @@ impl<'a> Context<'a> {
541549
_ => "",
542550
};
543551

544-
let ts = Self::ts_for_init_fn(has_memory, !default_module_path.is_empty());
552+
let ts = self.ts_for_init_fn(has_memory, !default_module_path.is_empty())?;
545553

546554
// Initialize the `imports` object for all import definitions that we're
547555
// directed to wire up.

crates/cli-support/src/wasm2es6js.rs

+49
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,55 @@ impl Config {
4444
}
4545
}
4646

47+
pub fn interface(module: &Module) -> Result<String, Error> {
48+
let mut exports = String::new();
49+
50+
for entry in module.exports.iter() {
51+
let id = match entry.item {
52+
walrus::ExportItem::Function(i) => i,
53+
walrus::ExportItem::Memory(_) => {
54+
exports.push_str(&format!(
55+
" readonly {}: WebAssembly.Memory;\n",
56+
entry.name,
57+
));
58+
continue;
59+
}
60+
walrus::ExportItem::Table(_) => {
61+
exports.push_str(&format!(
62+
" readonly {}: WebAssembly.Table;\n",
63+
entry.name,
64+
));
65+
continue;
66+
}
67+
walrus::ExportItem::Global(_) => continue,
68+
};
69+
70+
let func = module.funcs.get(id);
71+
let ty = module.types.get(func.ty());
72+
let mut args = String::new();
73+
for (i, _) in ty.params().iter().enumerate() {
74+
if i > 0 {
75+
args.push_str(", ");
76+
}
77+
args.push((b'a' + (i as u8)) as char);
78+
args.push_str(": number");
79+
}
80+
81+
exports.push_str(&format!(
82+
" readonly {name}: ({args}) => {ret};\n",
83+
name = entry.name,
84+
args = args,
85+
ret = match ty.results().len() {
86+
0 => "void",
87+
1 => "number",
88+
_ => "Array",
89+
},
90+
));
91+
}
92+
93+
Ok(exports)
94+
}
95+
4796
pub fn typescript(module: &Module) -> Result<String, Error> {
4897
let mut exports = format!("/* tslint:disable */\n/* eslint-disable */\n");
4998

0 commit comments

Comments
 (0)