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

Incorrect export class generation for typescript from golang struct #2602

Closed
phyce opened this issue Apr 16, 2023 · 6 comments · Fixed by #3978
Closed

Incorrect export class generation for typescript from golang struct #2602

phyce opened this issue Apr 16, 2023 · 6 comments · Fixed by #3978
Labels
awaiting feedback More information is required from the requestor Bug Something isn't working

Comments

@phyce
Copy link

phyce commented Apr 16, 2023

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"`
}
  1. 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

# 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.

@phyce phyce added the Bug Something isn't working label Apr 16, 2023
@phyce phyce changed the title Incorrect export class generation in for typescript from golang struct Incorrect export class generation for typescript from golang struct Apr 16, 2023
@mateothegreat
Copy link
Contributor

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
Copy link
Member

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

@phyce
Copy link
Author

phyce commented May 9, 2023

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
Copy link
Member

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

@leaanthony leaanthony added the awaiting feedback More information is required from the requestor label May 21, 2023
@agajdosi
Copy link

agajdosi commented May 8, 2024

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
Copy link
Author

phyce commented May 8, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting feedback More information is required from the requestor Bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants