Skip to content

Commit b79e433

Browse files
fix(bindgen): generate ancillary type generation for functions
This commit fixes an issue where ancillary types (like `Result<T>`) wouldn't get generated in TS bindings for exported functions in interfaces. Resolves #627
1 parent da6f55c commit b79e433

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

crates/js-component-bindgen/src/ts_bindgen.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ pub fn ts_bindgen(
179179
opts.instantiation.is_some(),
180180
);
181181
}
182+
182183
// namespaced ns:pkg/iface
183184
// TODO: map support
184185
WorldKey::Interface(id) => {
@@ -196,6 +197,7 @@ pub fn ts_bindgen(
196197
}
197198
}
198199
}
200+
199201
WorldItem::Type { id, .. } => {
200202
let ty = &resolve.types[*id];
201203
let name = ty.name.as_ref().unwrap();
@@ -211,6 +213,7 @@ pub fn ts_bindgen(
211213

212214
let mut generator = TsInterface::new(resolve, true, opts.guest);
213215
generator.docs(&ty.docs);
216+
214217
match &ty.kind {
215218
TypeDefKind::Record(record) => {
216219
generator.type_record(*id, name, record, &ty.docs)
@@ -275,6 +278,7 @@ pub fn ts_bindgen(
275278
unreachable!("unexpected interface export during export processing")
276279
}
277280
};
281+
278282
if !feature_gate_allowed(resolve, package, &f.stability, &f.name)
279283
.context("failed to check feature gate for export")?
280284
{
@@ -283,8 +287,10 @@ pub fn ts_bindgen(
283287
);
284288
continue;
285289
}
290+
286291
funcs.push((export_name.to_lower_camel_case(), f));
287292
}
293+
288294
WorldItem::Interface { id, stability, .. } => {
289295
let iface_id: String;
290296
let (export_name, iface_name): (&str, &str) = match name {
@@ -437,6 +443,7 @@ pub fn ts_bindgen(
437443
generate_references(&bindgen.references).as_bytes(),
438444
);
439445
files.push(&filename, bindgen.src.as_bytes());
446+
440447
Ok(())
441448
}
442449

@@ -603,6 +610,27 @@ impl TsBindgen {
603610
id_name,
604611
&self.async_exports,
605612
);
613+
614+
// Figure out whether we need ancillary types
615+
for ty in func.parameter_and_result_types() {
616+
if let Type::Id(typedef_id) = ty {
617+
let typedef_id = dealias(resolve, typedef_id);
618+
// For all complex func/param types that are used in this function, output
619+
// the relevant type definitions
620+
let result_ty_def = &resolve.types[typedef_id];
621+
match &result_ty_def.kind {
622+
TypeDefKind::Option(_) => {
623+
generator.needs_ty_option = true;
624+
}
625+
TypeDefKind::Result(_) => {
626+
generator.needs_ty_result = true;
627+
}
628+
_ => {}
629+
}
630+
}
631+
}
632+
633+
// Generate the function type definition
606634
generator.ts_func(
607635
func,
608636
false,
@@ -612,6 +640,8 @@ impl TsBindgen {
612640
);
613641
}
614642

643+
generator.post_types();
644+
615645
let (src, references) = generator.finish();
616646
self.export_object.push_str(&src);
617647
self.references.extend(references);

0 commit comments

Comments
 (0)