#[tsify(type_params = "...")] renames what the declaration declares, but the fields keep rendering the Rust parameter, so the two stop matching.
Reproducing
On 396867b:
#[derive(Tsify)]
#[tsify(type_params = "U")]
struct Foo<T> {
data: T,
}
export interface Foo<U> {
data: T;
}
error TS2304: Cannot find name 'T'.
U is declared and never used; T is used and never declared. The .d.ts does not type-check, and nothing in the build says so.
What is going on
The attribute replaces the declared parameter list wholesale. A field of type T is rendered from the Rust type, which still says T, and no pass reconciles the two. So the attribute is usable only when the names it gives happen to match the Rust parameters — which makes renaming, its apparent purpose, the case that breaks.
Where this sits
Same family as #94 and #103: tsify emits a reference to a name and never checks that anything declares it. #103 is where the general answer to that belongs; this one is narrow enough to fix without it. This one is narrower than those, since it needs the attribute to be present, and it has a clear fix inside the attribute rather than needing the general answer.
Two options, and I do not have a preference yet:
- Map the declared names back to the Rust parameters positionally, and render fields through that map.
- Reject a
type_params list whose names do not match the Rust parameters, and keep the attribute for adding bounds and defaults rather than renaming.
The second is a breaking change for anyone relying on the current behavior, though it is hard to rely on something that emits an undeclared name.
Notes
Not new, and not caused by #110 — I found it while reviewing that PR. It reproduces on main unchanged.
#[tsify(type_params = "...")]renames what the declaration declares, but the fields keep rendering the Rust parameter, so the two stop matching.Reproducing
On
396867b:Uis declared and never used;Tis used and never declared. The.d.tsdoes not type-check, and nothing in the build says so.What is going on
The attribute replaces the declared parameter list wholesale. A field of type
Tis rendered from the Rust type, which still saysT, and no pass reconciles the two. So the attribute is usable only when the names it gives happen to match the Rust parameters — which makes renaming, its apparent purpose, the case that breaks.Where this sits
Same family as #94 and #103: tsify emits a reference to a name and never checks that anything declares it. #103 is where the general answer to that belongs; this one is narrow enough to fix without it. This one is narrower than those, since it needs the attribute to be present, and it has a clear fix inside the attribute rather than needing the general answer.
Two options, and I do not have a preference yet:
type_paramslist whose names do not match the Rust parameters, and keep the attribute for adding bounds and defaults rather than renaming.The second is a breaking change for anyone relying on the current behavior, though it is hard to rely on something that emits an undeclared name.
Notes
Not new, and not caused by #110 — I found it while reviewing that PR. It reproduces on
mainunchanged.