Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

circularly reference on update #2001

Closed
Zetanova opened this issue May 27, 2024 · 10 comments
Closed

circularly reference on update #2001

Zetanova opened this issue May 27, 2024 · 10 comments

Comments

@Zetanova
Copy link

I get a tslint error when I try to use the following entity

//bufbuild generated class
export declare class User extends Message<User> {
  /**
   * @generated from field: string id = 1;
   */
  id: string;

  /**
   * @generated from field: string name = 3 [json_name = "n"];
   */
  name: string;

  /**
   * @generated from field: map<string, google.protobuf.Value> attributes = 10 [json_name = "atts"];
   */
  attributes: { [key: string]: Value };
 
  /**
   * @generated from field: google.protobuf.Value metadata = 25 [json_name = "meta"];
   */
  metadata?: Value;

  constructor(data?: PartialMessage<User>);

  //other stuff
}

//dexie table entity
export interface UserEntity {
  key: string,
  entry: PlainMessage<User>,
  //some other properties
}

This method call generates the error only if the UserEntity.attributes field is defined.

const entity:UserEntity

await db.users.update(entity, n => { })
//[ERROR] TS2615: Type of property 'values' circularly references itself in mapped type '{ values: "values" | `values.${number}` | `values.${number}.${any}`; }'

add, put methods working fine and I could narrow the issue down to attributes: { [key: string]: Value }; definition. But have now clue how to fix it.

@dfahlander
Copy link
Collaborator

Seems as a circular issue in the class definition of User as it extends a generic with itself as argument?

@Zetanova
Copy link
Author

the PlainMessage is only a helper to strip out the helper methods and description fields of the protobuf message
https://github.com/bufbuild/protobuf-es/blob/main/docs/runtime_api.md#plainmessage

The issue happens really only if the attributes: { [key: string]: Value } field exists

@dfahlander
Copy link
Collaborator

What is Value?

@Zetanova
Copy link
Author

It is a wellknown type of google.protobuf.Value
https://buf.build/protocolbuffers/wellknowntypes/docs/main:google.protobuf#google.protobuf.Value

The ts definition comes with the base package, most languages provide one for the wellknown types.

Found here:
https://www.npmjs.com/package/@bufbuild/protobuf?activeTab=code
/@bufbuild/protobuf/dist/cjs/google/protobuf/struct_pb.d.ts
line: 65 export declare class Value extends Message<Value> { ... }

The Value class used without the map works fine like with the metadata?: Value field

@dfahlander
Copy link
Collaborator

Please provide a repro

@Zetanova
Copy link
Author

@dfahlander Here is the repo to reproduce the issue https://github.com/Zetanova/dexie-issue-2001

dfahlander added a commit that referenced this issue May 27, 2024
dfahlander added a commit that referenced this issue May 27, 2024
Reorder overloaded update method so that if callback is provided TS at least do not care whether T is circular or not.
@dfahlander
Copy link
Collaborator

There's nothing we could do to support recursive types since the number of possible keypaths would be infinite. I wish we could fallback to any when this is the case but I haven't found any way to do it. PRs are welcome though ;)

What I could do at least is to change the declaration of the overloaded method Table.update() so that it won't complain about circular references if the callback version is used. Runtime, you could continue using the object overload though but you'd have to make TS compiler ignore the line with // @ts-ignore if so.

The provided repro compiles now at least but it's only using the callback overload.

@Zetanova
Copy link
Author

My typescript skill level is only medium and I don't really understand why the issue fully

What I discovered is that a field with value:Value produces a circularly references error
but an optional field (default in protobuf) does not, value?:Value works fine

Some goes for value:PlainMessage<Value> has the issue
but value:PartialMessage<Value> works

Maybe the dexie.KeyPaths<T> can output a optional value for map/record?

Compiler ignores are always a possibility
Maybe there is one to set it on dexie.KeyPaths<T> ?

I can workaround the issue over get/put

@dfahlander
Copy link
Collaborator

Since this is a typing issue only, it's probably better to workaround the issue by disabling typechecking only for the line that does table.update():

  // @ts-ignore
  db.someTable.update(...)

@Zetanova
Copy link
Author

thx, is the best current option

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants