Skip to content

type_params renames the declaration but not the fields that use it #113

Description

@madonoharu

#[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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions