wailsapp / wails

Create beautiful applications using Go
https://wails.io
MIT License
24.68k stars 1.18k forks source link

Incorrect export class generation for typescript from golang struct #2602

Open phyce opened 1 year ago

phyce commented 1 year ago

Description

This issue happens with versions 2.3.1 and 2.4.1 I have a project with Typescript + Wails.

The generated code in models.ts fails to build when adding json tags to a struct in which one of the Items is of type []time.Time

To Reproduce

  1. Add a struct with json tags to a project like the following:
    
    import "time"

type Options struct { CalendarStartupDates []time.Time json:"CalendarStartupDates" StartupTime time.Time json:"StartupTime" TimedShutdownTime time.Time json:"TimedShutdownTime" }

2. Build the project. The frontend will fail to compile. The generated class for this struct in Typescript is:
export class Options {
    CalendarStartupDates: time.Time[];
    // Go type: time
    StartupTime: any;
    // Go type: time
    TimedShutdownTime: any;
//...
    constructor(source: any = {}) {
        if ('string' === typeof source) source = JSON.parse(source);
        this.CalendarStartupDates = this.convertValues(source["CalendarStartupDates"], time.Time);
        this.StartupTime = this.convertValues(source["StartupTime"], null);
        this.TimedShutdownTime = this.convertValues(source["TimedShutdownTime"], null);
    }
//...
}

### Expected behaviour

I assume that the generated type for `CalendarStartupDates` should be `any[]` instead of `time.Time[]`.

### Screenshots

_No response_

### Attempted Fixes

Removing the json tags from the struct stops the build from failing. 
I have a custom interface for this data in my code so I don't really need it, but there doesn't seem to be any other way to stop this from being generated.

### System Details

```shell
# System

OS           | Windows 10 Home
Version      | 2009 (Build: 22621)
ID           | 22H2
Go Version   | go1.20
Platform     | windows
Architecture | amd64

# Wails

Version | v2.4.1

# Dependencies

Dependency | Package Name | Status    | Version
WebView2   | N/A          | Installed | 112.0.1722.39
npm        | N/A          | Installed | 8.15.0
*upx       | N/A          | Available |
*nsis      | N/A          | Available |
* - Optional Dependency

# Diagnosis

Your system is ready for Wails development!

Additional context

I stumbled upon this problem because I need the json tags in Go so that I can export data in json format to a file.

Also on a side note, wails doctor reports the OS is windows 10, when it's actually windows 11.

mateothegreat commented 1 year ago

Confirmed over here as well..

    Error: wailsjs/go/models.ts:24:12 - error TS2503: Cannot find namespace 'time'.

    24      time: time.Time[];
                  ~~~~

    Error: wailsjs/go/models.ts:34:57 - error TS2663: Cannot find name 'time'. Did you mean the instance member 'this.time'?

    34          this.time = this.convertValues(source["time"], time.Time);
                                                               ~~~~

Resulting models.ts:

    export class NetworkScanAddressResult {
        address: string;
        ports: NetworkScanPortResult[];
        time: time.Time[];

        static createFrom(source: any = {}) {
            return new NetworkScanAddressResult(source);
        }

        constructor(source: any = {}) {
            if ('string' === typeof source) source = JSON.parse(source);
            this.address = source["address"];
            this.ports = this.convertValues(source["ports"], NetworkScanPortResult);
            this.time = this.convertValues(source["time"], time.Time);
        }
leaanthony commented 1 year ago

Can you please try master as there's been some typescript generation updates merged.

phyce commented 1 year ago

I have just tried the master branch but the issue still seems to be there. I do however think that I might be doing something wrong.

I have added the following line to go.mod in my project: replace github.com/wailsapp/wails => ./wails/wails

I tried looking into the issue myself, but whenever I run go build -tags bindings -o bindings.exe it seems to use the release code, instead of my local copy, as none of the changes I added to the relevant code was being applied. I did see my changes being applied whenever I ran wails dev or wails build.

What am I doing wrong? Is there anything else that I need to do? I would love to contribute to this project in the future.

leaanthony commented 1 year ago

@phyce use replace github.com/wailsapp/wails/v2 => ./wails/wails/v2

agajdosi commented 4 months ago

Still happening with Wails v2.8.1.

type Post struct {
    UUID       string    `json:"uuid"`
    AuthorUUID string    `json:"author_uuid"`
    Text       string    `json:"text"`
    Reasoning  string    `json:"reasoning"`
    Created    time.Time `json:"created"`
    Error      error     `json:"error"`
}
    export class Post {
        uuid: string;
        author_uuid: string;
        text: string;
        reasoning: string;
        created: time.Time;
        error: any;

        static createFrom(source: any = {}) {
            return new Post(source);
        }

        constructor(source: any = {}) {
            if ('string' === typeof source) source = JSON.parse(source);
            this.uuid = source["uuid"];
            this.author_uuid = source["author_uuid"];
            this.text = source["text"];
            this.reasoning = source["reasoning"];
            this.created = this.convertValues(source["created"], time.Time);
            this.error = source["error"];
        }

        convertValues(a: any, classs: any, asMap: boolean = false): any {
            if (!a) {
                return a;
            }
            if (a.slice) {
                return (a as any[]).map(elem => this.convertValues(elem, classs));
            } else if ("object" === typeof a) {
                if (asMap) {
                    for (const key of Object.keys(a)) {
                        a[key] = new classs(a[key]);
                    }
                    return a;
                }
                return new classs(a);
            }
            return a;
        }
    }

Is there anything I could do? It works - I am able to access Created in typescript, just the npx tsc screams at me.

phyce commented 4 months ago

I tried recently and still had the same issue - a workaround I did was to simply not have the json export tags on the struct, and creating it manually in typescript