5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-02 11:10:47 +08:00
wails/v2/internal/binding/binding_test/binding_generics_test.go
Jeremy Jay c4fdfd6415
Fix miscellaneous bindings and typescript export bugs (#3978)
* Do not attempt to export fields that cannot be json-encoded

* update changelog w/ PR

* also skip UnsafePointers

* WIP to allow conversion from Go generic types to typescript

* support for non-primitive generics also :)

* fix generic types in parameters / return args

* fixes a namespacing bug when mapping to pointer to struct

* fixing invalid knownstructs

* found a place it mattered, pushing the star replacement to the generate side

* descend as much as necessary to find structs

caught these examples in http.Request.TLS:

PeerCertificates []*x509.Certificate
VerifiedChains [][]*x509.Certificate

* accidently reverted other fix

* switch syntax for typescript record outputs

prior syntax is primarily useful for naming keys
so not useful here, and this syntax avoids square
brackets in output which greatly simplifies
generation for Go generics

* better handle edge cases for nested arrays and slices

* lots o tests

* update changelog

---------

Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
2025-01-13 20:14:54 +11:00

155 lines
5.9 KiB
Go

package binding_test
import "github.com/wailsapp/wails/v2/internal/binding/binding_test/binding_test_import/float_package"
// Issues 3900, 3371, 2323 (no TS generics though)
type ListData[T interface{}] struct {
Total int64 `json:"Total"`
TotalPage int64 `json:"TotalPage"`
PageNum int `json:"PageNum"`
List []T `json:"List,omitempty"`
}
func (x ListData[T]) Get() ListData[T] {
return x
}
var Generics1Test = BindingTest{
name: "Generics1",
structs: []interface{}{
&ListData[string]{},
},
exemptions: nil,
shouldError: false,
want: `
export namespace binding_test {
export class ListData_string_ {
Total: number;
TotalPage: number;
PageNum: number;
List?: string[];
static createFrom(source: any = {}) {
return new ListData_string_(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.Total = source["Total"];
this.TotalPage = source["TotalPage"];
this.PageNum = source["PageNum"];
this.List = source["List"];
}
}
}
`,
}
var Generics2Test = BindingTest{
name: "Generics2",
structs: []interface{}{
&ListData[float_package.SomeStruct]{},
&ListData[*float_package.SomeStruct]{},
},
exemptions: nil,
shouldError: false,
want: `
export namespace binding_test {
export class ListData__github_com_wailsapp_wails_v2_internal_binding_binding_test_binding_test_import_float_package_SomeStruct_ {
Total: number;
TotalPage: number;
PageNum: number;
List?: float_package.SomeStruct[];
static createFrom(source: any = {}) {
return new ListData__github_com_wailsapp_wails_v2_internal_binding_binding_test_binding_test_import_float_package_SomeStruct_(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.Total = source["Total"];
this.TotalPage = source["TotalPage"];
this.PageNum = source["PageNum"];
this.List = this.convertValues(source["List"], float_package.SomeStruct);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
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;
}
}
export class ListData_github_com_wailsapp_wails_v2_internal_binding_binding_test_binding_test_import_float_package_SomeStruct_ {
Total: number;
TotalPage: number;
PageNum: number;
List?: float_package.SomeStruct[];
static createFrom(source: any = {}) {
return new ListData_github_com_wailsapp_wails_v2_internal_binding_binding_test_binding_test_import_float_package_SomeStruct_(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.Total = source["Total"];
this.TotalPage = source["TotalPage"];
this.PageNum = source["PageNum"];
this.List = this.convertValues(source["List"], float_package.SomeStruct);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
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;
}
}
}
export namespace float_package {
export class SomeStruct {
string: string;
static createFrom(source: any = {}) {
return new SomeStruct(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.string = source["string"];
}
}
}
`,
}