Skip to content

Bug: opt int fields sometimes generated as required bigint instead of [] | [bigint] in TypeScript #144

Description

@DappjakLabs

Summary

@icp-sdk/bindgen incorrectly generates some opt int fields as a required bigint in both the TypeScript types and the embedded IDL factory, while correctly generating other identical opt int fields as [] | [bigint] and IDL.Opt(IDL.Int).

This breaks type safety and runtime IDL consistency for affected records (VideoComment, Post, etc.).

Affected Fields

Correctly generated:

  • VideoPublishing.scheduledDate: opt int'scheduledDate' : [] | [bigint]

Incorrectly generated:

  • VideoComment.timestampEdited: opt int'timestampEdited' : bigint (should be [] | [bigint])
  • Post.timestampEdited: opt int → also generated as bigint

Evidence

1. Candid source (both fields defined identically as opt int):

type VideoPublishing = 
 record {
   scheduledDate: opt int;
   // ...
 };

type VideoComment = 
 record {
   timestampEdited: opt int;
   // ...
 };
  1. Generated TypeScript (backend.did.ts):
TypeScript// ✅ Correct
'scheduledDate' : [] | [bigint],

// ❌ Wrong
'timestampEdited' : bigint,   // should be [] | [bigint]
  1. Embedded IDL factory (also broken):
TypeScriptconst VideoComment = IDL.Record({
  ...
  'timestampEdited' : IDL.Int,           // ← should be IDL.Opt(IDL.Int)
  ...
});

Reproduction Steps

Bashnpx @icp-sdk/bindgen \
  --did-file ./backend.did \
  --out-dir ./src/lib/declarations/backend \
  --force

Check output:

Bashrg "'timestampEdited'|'scheduledDate'" ./src/lib/declarations/backend/backend.did.ts
Environment

Bindgen version: @icp-sdk/bindgen@0.4.0 (latest)
Generated from pipeline: shared/schema.ts → Motoko → .did (both fields have optional: true)

Expected Behavior
All opt int fields should consistently produce:

TypeScript: [] | [bigint]
IDL: IDL.Opt(IDL.Int)

Additional Notes

The raw .did file is valid and contains opt int for both fields.
The bug is selective (some opt int fields work, others don't) → likely a parser / type resolution / substitution issue in the Rust codegen.
This affects both rich TS types and the runtime IDL definitions.

Minimum reproducible did:

backend-minimal.did.txt

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions