o1js icon indicating copy to clipboard operation
o1js copied to clipboard

seemingly-innocuous code producing checker depth error (2589)

Open harrysolovay opened this issue 10 months ago • 5 comments

I see no circular type reference in the following.

import { Struct, UInt64, MerkleList } from "o1js"

export class ApprovalId extends UInt64 {}
export class Approvals extends MerkleList<ApprovalId> {}

export class TokenAccount extends Struct({
  balance: UInt64,
  approvals: Approvals,
}) {}

Any idea why this is producing a type instantiation depth error?

TS playground here.

harrysolovay avatar Apr 05 '24 12:04 harrysolovay

import { Struct, UInt64, MerkleList } from "o1js"

export class ApprovalId extends UInt64 {}
-export class Approvals extends MerkleList<ApprovalId> {}
+export class Approvals extends MerkleList.create(ApprovalId) {}

export class TokenAccount extends Struct({
  balance: UInt64,
- approvals: Approvals,
+ approvals: Approvals.provable,
}) {}

mitschabaude avatar Apr 05 '24 12:04 mitschabaude

we still need to make the change to handle .provable https://github.com/o1-labs/o1js/issues/1248

mitschabaude avatar Apr 05 '24 12:04 mitschabaude

Also I think we should add a recursive base type for inputs to Struct, which would be a clearer error

mitschabaude avatar Apr 05 '24 13:04 mitschabaude

Thank you for the quick reply and (temporary (?)) fix. I can confirm that resolved the depth error. Why is MerkleList a class and not a class factory like Struct?

harrysolovay avatar Apr 05 '24 14:04 harrysolovay

We need base classes for generic classes because if we return them directly from a function, the type gets butchered by TS in the exported d.ts file. For example, method arguments that are instances of the class become any.

For Struct it's different because we're explicitly defining the interface that the function returns.

mitschabaude avatar Apr 05 '24 15:04 mitschabaude