zen-fs / core

A filesystem, anywhere
https://zen-fs.github.io/core/
MIT License
71 stars 10 forks source link

`configure` example with `Zip` gives a type error #87

Closed robert-westenberger closed 1 week ago

robert-westenberger commented 2 weeks ago

Reproduction: https://stackblitz.com/edit/vitejs-vite-ud11r8?file=src%2FcreateFilesystem.ts

I am using the following for the reproduction

"dependencies": {
    "@zenfs/core": "0.12.10",
    "@zenfs/dom": "0.2.13",
    "@zenfs/zip": "0.4.5"
  }

The code is copied verbatim from an example of using configure from the @zenfs/core@0.12.10 readme. https://github.com/zen-fs/core/blob/772e05416541748257491678b13200850f23ed75/readme.md?plain=1#L57-L69

The error

No overload matches this call.
  Overload 1 of 2, '(config: MountConfiguration<Backend<FileSystem, object>>): Promise<void>', gave the following error.
    Argument of type '{ mounts: { '/mnt/zip': { backend: { name: string; options: { data: { type: "object"; required: true; description: string; validator(buff: unknown): void; }; name: { type: "string"; required: false; description: string; }; }; isAvailable(): boolean; create(options: ZipOptions): ZipFS; }; zipData: ArrayBuffer; }; '/t...' is not assignable to parameter of type 'MountConfiguration<Backend<FileSystem, object>>'.
      Object literal may only specify known properties, and 'mounts' does not exist in type 'MountConfiguration<Backend<FileSystem, object>>'.
  Overload 2 of 2, '(config: Partial<Configuration<ConfigMounts>>): Promise<void>', gave the following error.
    Type '{ backend: { name: string; options: { data: { type: "object"; required: true; description: string; validator(buff: unknown): void; }; name: { type: "string"; required: false; description: string; }; }; isAvailable(): boolean; create(options: ZipOptions): ZipFS; }; zipData: ArrayBuffer; }' is not assignable to type 'MountConfiguration<Backend<FileSystem, object>>'.
      Object literal may only specify known properties, and 'zipData' does not exist in type 'MountConfiguration<Backend<FileSystem, object>>'.(2769)

Love the library! Great stuff.

james-pre commented 2 weeks ago

This is because the option name change from zipData to just data. The error is not very clear however. I've updated the readme.

Thanks for supporting the project!

robert-westenberger commented 1 week ago

https://stackblitz.com/edit/vitejs-vite-2fp3vt?file=src%2FcreateFilesystem.ts

Like this?

await configure({
  mounts: {
    '/mnt/zip': { backend: Zip, data: zipData },
    '/tmp': InMemory,
    '/home': IndexedDB,
  },
});

Hmm, I still get an error. It's still complaining about the mounts key not existing on the MountConfiguration type. And data doesnt exist either, did that get changed in @zenfs/core > 0.12.0 ?

No overload matches this call.
  Overload 1 of 2, '(config: MountConfiguration<Backend<FileSystem, object>>): Promise<void>', gave the following error.
Argument of type '{ mounts: { '/mnt/zip': { backend: { name: string; options: { data: { type: "object"; required: true; description: string; validator(buff: unknown): void; }; name: { type: "string"; required: false; description: string; }; }; isAvailable(): boolean; create(options: ZipOptions): ZipFS; }; data: ArrayBuffer; }; '/tmp'...' is not assignable to parameter of type 'MountConfiguration<Backend<FileSystem, object>>'.
Object literal may only specify known properties, and 'mounts' does not exist in type 'MountConfiguration<Backend<FileSystem, object>>'.
  Overload 2 of 2, '(config: Partial<Configuration<ConfigMounts>>): Promise<void>', gave the following error.
Type '{ backend: { name: string; options: { data: { type: "object"; required: true; description: string; validator(buff: unknown): void; }; name: { type: "string"; required: false; description: string; }; }; isAvailable(): boolean; create(options: ZipOptions): ZipFS; }; data: ArrayBuffer; }' is not assignable to type 'MountConfiguration<Backend<FileSystem, object>>'.
      Object literal may only specify known properties, and 'data' does not exist in type 'MountConfiguration<Backend<FileSystem, object>>'
james-pre commented 1 week ago

The second overload should have worked. Perhaps the extends clause of the type is incorrect? I believe the type may not be correctly assignable to BackendConfiguration due to the options being object, and a type like Record<Exclude<string, 'backend'>, unknown> might work.

The current fix is to pass typeof Zip (or whatever backend you are using) as a type parameter. The type acquisition should be automatic though, and I will debug it as soon as I can.

Thanks.

james-pre commented 1 week ago

@robert-westenberger,

I found that having 2 different overloads and sets of behavior complicates debugging both for maintainers and users. 0.15.0 aims to fix this by introducing the configureSingle function, which acts like resolveMountConfig but also handles the unmounting of the old root and mounting of the new root.

I've tested the changes locally, and it appears that Typescript correctly picks up when properties are missing and reports that to the user. You will need to update @zenfs/core but @zenfs/zip should not need any modification to work with the latest core release.

Thanks, JP

robert-westenberger commented 1 week ago

Awesome, thank you james!

robert-westenberger commented 1 week ago

Closing this as resolved.