subsquid / squid-sdk

The main repo of the squid SDK
Apache License 2.0
1.23k stars 151 forks source link

Objects containing Enum fields cause build failures #97

Closed theodorebugnet closed 2 years ago

theodorebugnet commented 2 years ago

Consider a schema such as:

enum MyEnum {
  A
  B
}

type MyObject {
  enumField: MyEnum!
}

codegen will then generate a src/model/generated/_myObject.ts file, containing a constructor that allows deserializing from JSON using marshal. However, it treats the enum field as a string, causing the typescript build to fail (with the error Type 'string' is not assignable to type 'MyEnum'.):

  constructor(props?: Partial<Omit<MyObject, 'toJSON'>>, json?: any) {
    Object.assign(this, props)
    if (json != null) {
      this._enumField = marshal.string.fromJSON(json.enumField)
    }
  }

I believe the fix would be to generate a type cast for the enum type, e.g.

      this._enumField = marshal.string.fromJSON(json.enumField) as MyEnum
belopash commented 2 years ago

Are you using the latest version of the codegen package? This issue has already been fixed. There should be special function in marshal.ts to deal with enums.

export function enumFromJson<E extends object>(json: unknown, enumObject: E): E[keyof E] {
    assert(typeof json == 'string', 'invalid enum value')
    let val = (enumObject as any)[json]
    assert(typeof val == 'string', `invalid enum value`)
    return val as any
}