Skip to content

Bug: variant with a payload and a non-identifier tag generates invalid TypeScript in the conversion function #160

Description

@marc0olo

Pre-existing on main and on @icp-sdk/bindgen@0.4.0. Found while extending test fixtures for #156, but a distinct root cause — that issue is about binding positions, this one is about property and member-access positions in the generated conversion functions.

#152 fixed reserved-word tags for all-null variants (which become enums). Variants with payloads take a different path and still emit the raw tag unquoted.

Reproduction

printf 'type Outcome = variant { "ok-value": nat; "err-value": text };\nservice : () -> { run: () -> (Outcome) }\n' > payload.did
npx @icp-sdk/bindgen@0.4.0 --did-file ./payload.did --out-dir ./out --force

out/payload.ts:

return "ok-value" in value ? {
    __kind__: "ok-value",
    ok-value: value.ok-value      // ← two separate errors on one line
} : ...

Two faults:

  1. Object literal key: ok-value: must be quoted — 'ok-value':
  2. Member access: value.ok-value must be computed — value["ok-value"]

The type declarations above it are correct ('ok-value': bigint), so only the conversion function body is affected.

payload.ts(88,15): error TS1005: ',' expected.
payload.ts(89,1):  error TS1128: Declaration or statement expected.
... 6 errors total

Not masked by the file's // @ts-nocheck — these are parse errors.

Notes

The machinery to do this correctly already exists and is used elsewhere: contains_unicode_characters guards member access for method names in compile_wrapper.rs, and get_ident_guarded_keyword_ok quotes property keys. The payload-variant conversion path in conversion_functions_generator.rs does neither.

Worth checking the same path for records with non-identifier field names, which may have the same gap.

Scope

variant generated code
variant { "my-tag"; other } (all null) ✅ correct
variant { "my-tag": nat } (payload) ❌ invalid TypeScript
reserved-word tag with payload (variant { new: nat }) worth checking

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingrustPull requests that update rust code

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions