mirror of
https://github.com/wailsapp/wails.git
synced 2026-03-14 14:45:49 +01:00
Improved bindings generation: support JS Models.
This commit is contained in:
parent
23c2660fb0
commit
182f43004a
11 changed files with 448 additions and 72 deletions
|
|
@ -3,6 +3,7 @@ package flags
|
|||
type GenerateBindingsOptions struct {
|
||||
Silent bool `name:"silent" description:"Silent mode"`
|
||||
ModelsFilename string `name:"m" description:"The filename for the models file" default:"models.ts"`
|
||||
TS bool `name:"ts" description:"Generate Typescript bindings"`
|
||||
TSPrefix string `description:"The prefix for the typescript names" default:""`
|
||||
TSSuffix string `description:"The postfix for the typescript names" default:""`
|
||||
UseInterfaces bool `name:"i" description:"Use interfaces instead of classes"`
|
||||
|
|
|
|||
|
|
@ -20,9 +20,12 @@ type ModelDefinitions struct {
|
|||
}
|
||||
|
||||
func GenerateModel(wr io.Writer, def *ModelDefinitions, options *flags.GenerateBindingsOptions) error {
|
||||
templateName := "model.ts.tmpl"
|
||||
if options.UseInterfaces {
|
||||
templateName = "interfaces.ts.tmpl"
|
||||
templateName := "model.js.tmpl"
|
||||
if options.TS {
|
||||
templateName = "model.ts.tmpl"
|
||||
if options.UseInterfaces {
|
||||
templateName = "interfaces.ts.tmpl"
|
||||
}
|
||||
}
|
||||
|
||||
// Fix up TS names
|
||||
|
|
|
|||
|
|
@ -12,53 +12,103 @@ import (
|
|||
func TestGenerateModels(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
dir string
|
||||
want string
|
||||
useInterface bool
|
||||
name string
|
||||
dir string
|
||||
want string
|
||||
useInterface bool
|
||||
useTypescript bool
|
||||
}{
|
||||
{
|
||||
dir: "testdata/function_single",
|
||||
name: "function single",
|
||||
dir: "testdata/function_single",
|
||||
useTypescript: true,
|
||||
},
|
||||
{
|
||||
name: "function from imported package",
|
||||
dir: "testdata/function_from_imported_package",
|
||||
want: getFile("testdata/function_from_imported_package/models.ts"),
|
||||
useTypescript: true,
|
||||
},
|
||||
{
|
||||
name: "function from imported package (Javascript)",
|
||||
dir: "testdata/function_from_imported_package",
|
||||
want: getFile("testdata/function_from_imported_package/models.ts"),
|
||||
want: getFile("testdata/function_from_imported_package/models.js"),
|
||||
},
|
||||
{
|
||||
dir: "testdata/variable_single",
|
||||
name: "variable single",
|
||||
dir: "testdata/variable_single",
|
||||
useTypescript: true,
|
||||
},
|
||||
{
|
||||
dir: "testdata/variable_single_from_function",
|
||||
name: "variable single from function",
|
||||
dir: "testdata/variable_single_from_function",
|
||||
useTypescript: true,
|
||||
},
|
||||
{
|
||||
dir: "testdata/variable_single_from_other_function",
|
||||
want: getFile("testdata/variable_single_from_other_function/models.ts"),
|
||||
name: "variable single from other function",
|
||||
dir: "testdata/variable_single_from_other_function",
|
||||
want: getFile("testdata/variable_single_from_other_function/models.ts"),
|
||||
useTypescript: true,
|
||||
},
|
||||
{
|
||||
dir: "testdata/struct_literal_single",
|
||||
want: getFile("testdata/struct_literal_single/models.ts"),
|
||||
name: "struct literal single",
|
||||
dir: "testdata/struct_literal_single",
|
||||
want: getFile("testdata/struct_literal_single/models.ts"),
|
||||
useTypescript: true,
|
||||
},
|
||||
{
|
||||
dir: "testdata/struct_literal_multiple",
|
||||
name: "struct literal multiple",
|
||||
dir: "testdata/struct_literal_multiple",
|
||||
useTypescript: true,
|
||||
},
|
||||
{
|
||||
name: "struct literal multiple other",
|
||||
dir: "testdata/struct_literal_multiple_other",
|
||||
want: getFile("testdata/struct_literal_multiple_other/models.ts"),
|
||||
useTypescript: true,
|
||||
},
|
||||
{
|
||||
name: "struct literal multiple other (Javascript)",
|
||||
dir: "testdata/struct_literal_multiple_other",
|
||||
want: getFile("testdata/struct_literal_multiple_other/models.ts"),
|
||||
want: getFile("testdata/struct_literal_multiple_other/models.js"),
|
||||
},
|
||||
{
|
||||
dir: "testdata/struct_literal_multiple_files",
|
||||
name: "struct literal non pointer single (Javascript)",
|
||||
dir: "testdata/struct_literal_non_pointer_single",
|
||||
want: getFile("testdata/struct_literal_non_pointer_single/models.ts"),
|
||||
useTypescript: true,
|
||||
},
|
||||
{
|
||||
name: "struct literal non pointer single (Javascript)",
|
||||
dir: "testdata/struct_literal_non_pointer_single",
|
||||
want: getFile("testdata/struct_literal_non_pointer_single/models.js"),
|
||||
},
|
||||
{
|
||||
name: "struct literal multiple files",
|
||||
dir: "testdata/struct_literal_multiple_files",
|
||||
useTypescript: true,
|
||||
},
|
||||
{
|
||||
name: "enum",
|
||||
dir: "testdata/enum",
|
||||
want: getFile("testdata/enum/models.ts"),
|
||||
useTypescript: true,
|
||||
},
|
||||
{
|
||||
name: "enum (Javascript)",
|
||||
dir: "testdata/enum",
|
||||
want: getFile("testdata/enum/models.ts"),
|
||||
want: getFile("testdata/enum/models.js"),
|
||||
},
|
||||
{
|
||||
dir: "testdata/enum-interface",
|
||||
want: getFile("testdata/enum-interface/models.ts"),
|
||||
useInterface: true,
|
||||
name: "enum interface",
|
||||
dir: "testdata/enum-interface",
|
||||
want: getFile("testdata/enum-interface/models.ts"),
|
||||
useInterface: true,
|
||||
useTypescript: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.dir, func(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Run parser on directory
|
||||
project, err := ParseProject(tt.dir)
|
||||
if err != nil {
|
||||
|
|
@ -68,6 +118,7 @@ func TestGenerateModels(t *testing.T) {
|
|||
// Generate Models
|
||||
got, err := GenerateModels(project.Models, project.Types, &flags.GenerateBindingsOptions{
|
||||
UseInterfaces: tt.useInterface,
|
||||
TS: tt.useTypescript,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateModels() error = %v", err)
|
||||
|
|
@ -76,7 +127,11 @@ func TestGenerateModels(t *testing.T) {
|
|||
got = convertLineEndings(got)
|
||||
want := convertLineEndings(tt.want)
|
||||
if diff := cmp.Diff(want, got); diff != "" {
|
||||
err = os.WriteFile(filepath.Join(tt.dir, "models.got.ts"), []byte(got), 0644)
|
||||
gotFilename := "models.got.js"
|
||||
if tt.useTypescript {
|
||||
gotFilename = "models.got.ts"
|
||||
}
|
||||
err = os.WriteFile(filepath.Join(tt.dir, gotFilename), []byte(got), 0644)
|
||||
if err != nil {
|
||||
t.Errorf("os.WriteFile() error = %v", err)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -181,6 +181,39 @@ func (f *Field) JSDef(pkg string) string {
|
|||
return result
|
||||
}
|
||||
|
||||
func (f *Field) JSDocType(pkg string) string {
|
||||
var jsType string
|
||||
switch f.Type.Name {
|
||||
case "int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16", "uint32", "uint64", "uintptr", "float32", "float64":
|
||||
jsType = "number"
|
||||
case "string":
|
||||
jsType = "string"
|
||||
case "bool":
|
||||
jsType = "boolean"
|
||||
default:
|
||||
jsType = f.Type.Name
|
||||
}
|
||||
|
||||
var result string
|
||||
isExternalStruct := f.Type.Package != "" && f.Type.Package != pkg && f.Type.IsStruct
|
||||
if f.Type.Package == "" || f.Type.Package == pkg || !isExternalStruct {
|
||||
if f.Type.IsStruct || f.Type.IsEnum {
|
||||
result = fmt.Sprintf("%s.%s", pkg, jsType)
|
||||
} else {
|
||||
result = jsType
|
||||
}
|
||||
} else {
|
||||
parts := strings.Split(f.Type.Package, "/")
|
||||
result += fmt.Sprintf("%s.%s", parts[len(parts)-1], jsType)
|
||||
}
|
||||
|
||||
if !ast.IsExported(f.Name) {
|
||||
result += " // Warning: this is unexported in the Go struct."
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (f *Field) DefaultValue() string {
|
||||
// Return the default value of the typescript version of the type as a string
|
||||
switch f.Type.Name {
|
||||
|
|
@ -699,8 +732,8 @@ func (p *Project) getStructDef(name string, pkg *ParsedPackage) bool {
|
|||
if structType, ok := typeSpec.Type.(*ast.StructType); ok {
|
||||
if typeSpec.Name.Name == name {
|
||||
result := &StructDef{
|
||||
Name: name,
|
||||
DocComment: typeDecl.Doc.Text(),
|
||||
Name: name,
|
||||
//TODO DocComment: CommentGroupToText(typeDecl.Doc),
|
||||
}
|
||||
pkg.StructCache[name] = result
|
||||
result.Fields = p.parseStructFields(structType, pkg)
|
||||
|
|
|
|||
41
v3/internal/parser/templates/model.js.tmpl
Normal file
41
v3/internal/parser/templates/model.js.tmpl
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
{{$pkg := .Package}}
|
||||
// Defining the {{$pkg}} namespace
|
||||
export const {{$pkg}} = {};
|
||||
{{range $enumindex, $enumdef := .Enums}}
|
||||
// Simulating the enum with an object
|
||||
{{$pkg}}.{{$enumdef.Name}} = {
|
||||
{{- range $constindex, $constdef := .Consts}}
|
||||
{{- if $constdef.DocComment}}
|
||||
// {{$constdef.DocComment}}
|
||||
{{- end}}
|
||||
{{$constdef.Name}}: {{$constdef.Value}},{{end}}
|
||||
};
|
||||
{{- end}}
|
||||
{{range $name, $def := .Models}}
|
||||
{{- if $def.DocComment}}
|
||||
// {{$def.DocComment}}
|
||||
{{- end -}}
|
||||
{{$pkg}}.{{$def.Name}} = class {
|
||||
/**
|
||||
* Creates a new {{$def.Name}} instance.
|
||||
* @constructor
|
||||
* @param {Object} source - The source object to create the {{$def.Name}}.
|
||||
{{- range $field := $def.Fields}}
|
||||
* @param { {{- .JSDocType $pkg -}} } source.{{$field.Name}}{{end}}
|
||||
*/
|
||||
constructor(source = {}) {
|
||||
const { {{$def.DefaultValueList}} } = source; {{range $def.Fields}}
|
||||
this.{{.JSName}} = {{.JSName}};{{end}}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {{$def.Name}} instance from a string or object.
|
||||
* @param {string|object} source - The source data to create a {{$def.Name}} instance from.
|
||||
* @returns {{$pkg}}.{{$def.Name}} A new {{$def.Name}} instance.
|
||||
*/
|
||||
static createFrom(source = {}) {
|
||||
let parsedSource = typeof source === 'string' ? JSON.parse(source) : source;
|
||||
return new {{$pkg}}.{{$def.Name}}(parsedSource);
|
||||
}
|
||||
};
|
||||
{{end}}
|
||||
1
v3/internal/parser/testdata/enum/main.go
vendored
1
v3/internal/parser/testdata/enum/main.go
vendored
|
|
@ -25,6 +25,7 @@ type GreetService struct {
|
|||
target *Person
|
||||
}
|
||||
|
||||
// Person represents a person
|
||||
type Person struct {
|
||||
Title Title
|
||||
Name string
|
||||
|
|
|
|||
41
v3/internal/parser/testdata/enum/models.js
vendored
Normal file
41
v3/internal/parser/testdata/enum/models.js
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
// @ts-check
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
// Defining the main namespace
|
||||
export const main = {};
|
||||
|
||||
// Simulating the enum with an object
|
||||
main.Title = {
|
||||
// Mister is a title
|
||||
Mister: "Mr",
|
||||
Miss: "Miss",
|
||||
Ms: "Ms",
|
||||
Mrs: "Mrs",
|
||||
Dr: "Dr",
|
||||
};
|
||||
main.Person = class {
|
||||
/**
|
||||
* Creates a new Person instance.
|
||||
* @constructor
|
||||
* @param {Object} source - The source object to create the Person.
|
||||
* @param {main.Title} source.Title
|
||||
* @param {string} source.Name
|
||||
*/
|
||||
constructor(source = {}) {
|
||||
const { title = null, name = "" } = source;
|
||||
this.title = title;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Person instance from a string or object.
|
||||
* @param {string|object} source - The source data to create a Person instance from.
|
||||
* @returns main.Person A new Person instance.
|
||||
*/
|
||||
static createFrom(source = {}) {
|
||||
let parsedSource = typeof source === 'string' ? JSON.parse(source) : source;
|
||||
return new main.Person(parsedSource);
|
||||
}
|
||||
};
|
||||
|
||||
63
v3/internal/parser/testdata/function_from_imported_package/models.js
vendored
Normal file
63
v3/internal/parser/testdata/function_from_imported_package/models.js
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
// @ts-check
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
// Defining the main namespace
|
||||
export const main = {};
|
||||
|
||||
main.Person = class {
|
||||
/**
|
||||
* Creates a new Person instance.
|
||||
* @constructor
|
||||
* @param {Object} source - The source object to create the Person.
|
||||
* @param {string} source.Name
|
||||
* @param {services.Address} source.Address
|
||||
*/
|
||||
constructor(source = {}) {
|
||||
const { name = "", address = null } = source;
|
||||
this.name = name;
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Person instance from a string or object.
|
||||
* @param {string|object} source - The source data to create a Person instance from.
|
||||
* @returns main.Person A new Person instance.
|
||||
*/
|
||||
static createFrom(source = {}) {
|
||||
let parsedSource = typeof source === 'string' ? JSON.parse(source) : source;
|
||||
return new main.Person(parsedSource);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Defining the services namespace
|
||||
export const services = {};
|
||||
|
||||
services.Address = class {
|
||||
/**
|
||||
* Creates a new Address instance.
|
||||
* @constructor
|
||||
* @param {Object} source - The source object to create the Address.
|
||||
* @param {string} source.Street
|
||||
* @param {string} source.State
|
||||
* @param {string} source.Country
|
||||
*/
|
||||
constructor(source = {}) {
|
||||
const { street = "", state = "", country = "" } = source;
|
||||
this.street = street;
|
||||
this.state = state;
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Address instance from a string or object.
|
||||
* @param {string|object} source - The source data to create a Address instance from.
|
||||
* @returns services.Address A new Address instance.
|
||||
*/
|
||||
static createFrom(source = {}) {
|
||||
let parsedSource = typeof source === 'string' ? JSON.parse(source) : source;
|
||||
return new services.Address(parsedSource);
|
||||
}
|
||||
};
|
||||
|
||||
63
v3/internal/parser/testdata/struct_literal_multiple_other/models.js
vendored
Normal file
63
v3/internal/parser/testdata/struct_literal_multiple_other/models.js
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
// @ts-check
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
// Defining the main namespace
|
||||
export const main = {};
|
||||
|
||||
main.Person = class {
|
||||
/**
|
||||
* Creates a new Person instance.
|
||||
* @constructor
|
||||
* @param {Object} source - The source object to create the Person.
|
||||
* @param {string} source.Name
|
||||
* @param {services.Address} source.Address
|
||||
*/
|
||||
constructor(source = {}) {
|
||||
const { name = "", address = null } = source;
|
||||
this.name = name;
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Person instance from a string or object.
|
||||
* @param {string|object} source - The source data to create a Person instance from.
|
||||
* @returns main.Person A new Person instance.
|
||||
*/
|
||||
static createFrom(source = {}) {
|
||||
let parsedSource = typeof source === 'string' ? JSON.parse(source) : source;
|
||||
return new main.Person(parsedSource);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Defining the services namespace
|
||||
export const services = {};
|
||||
|
||||
services.Address = class {
|
||||
/**
|
||||
* Creates a new Address instance.
|
||||
* @constructor
|
||||
* @param {Object} source - The source object to create the Address.
|
||||
* @param {string} source.Street
|
||||
* @param {string} source.State
|
||||
* @param {string} source.Country
|
||||
*/
|
||||
constructor(source = {}) {
|
||||
const { street = "", state = "", country = "" } = source;
|
||||
this.street = street;
|
||||
this.state = state;
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Address instance from a string or object.
|
||||
* @param {string|object} source - The source data to create a Address instance from.
|
||||
* @returns services.Address A new Address instance.
|
||||
*/
|
||||
static createFrom(source = {}) {
|
||||
let parsedSource = typeof source === 'string' ? JSON.parse(source) : source;
|
||||
return new services.Address(parsedSource);
|
||||
}
|
||||
};
|
||||
|
||||
80
v3/internal/parser/testdata/struct_literal_non_pointer_single/models.js
vendored
Normal file
80
v3/internal/parser/testdata/struct_literal_non_pointer_single/models.js
vendored
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
// @ts-check
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
// Defining the main namespace
|
||||
export const main = {};
|
||||
|
||||
main.Person = class {
|
||||
/**
|
||||
* Creates a new Person instance.
|
||||
* @constructor
|
||||
* @param {Object} source - The source object to create the Person.
|
||||
* @param {string} source.Name
|
||||
* @param {main.Person} source.Parent
|
||||
* @param {main.anon1} source.Details
|
||||
*/
|
||||
constructor(source = {}) {
|
||||
const { name = "", parent = null, details = null } = source;
|
||||
this.name = name;
|
||||
this.parent = parent;
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Person instance from a string or object.
|
||||
* @param {string|object} source - The source data to create a Person instance from.
|
||||
* @returns main.Person A new Person instance.
|
||||
*/
|
||||
static createFrom(source = {}) {
|
||||
let parsedSource = typeof source === 'string' ? JSON.parse(source) : source;
|
||||
return new main.Person(parsedSource);
|
||||
}
|
||||
};
|
||||
main.anon1 = class {
|
||||
/**
|
||||
* Creates a new anon1 instance.
|
||||
* @constructor
|
||||
* @param {Object} source - The source object to create the anon1.
|
||||
* @param {number} source.Age
|
||||
* @param {main.anon2} source.Address
|
||||
*/
|
||||
constructor(source = {}) {
|
||||
const { age = 0, address = null } = source;
|
||||
this.age = age;
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new anon1 instance from a string or object.
|
||||
* @param {string|object} source - The source data to create a anon1 instance from.
|
||||
* @returns main.anon1 A new anon1 instance.
|
||||
*/
|
||||
static createFrom(source = {}) {
|
||||
let parsedSource = typeof source === 'string' ? JSON.parse(source) : source;
|
||||
return new main.anon1(parsedSource);
|
||||
}
|
||||
};
|
||||
main.anon2 = class {
|
||||
/**
|
||||
* Creates a new anon2 instance.
|
||||
* @constructor
|
||||
* @param {Object} source - The source object to create the anon2.
|
||||
* @param {string} source.Street
|
||||
*/
|
||||
constructor(source = {}) {
|
||||
const { street = "" } = source;
|
||||
this.street = street;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new anon2 instance from a string or object.
|
||||
* @param {string|object} source - The source data to create a anon2 instance from.
|
||||
* @returns main.anon2 A new anon2 instance.
|
||||
*/
|
||||
static createFrom(source = {}) {
|
||||
let parsedSource = typeof source === 'string' ? JSON.parse(source) : source;
|
||||
return new main.anon2(parsedSource);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -3,62 +3,57 @@
|
|||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
export namespace main {
|
||||
|
||||
export class Person {
|
||||
name: string;
|
||||
parent: Person;
|
||||
details: anon1;
|
||||
|
||||
static createFrom(source: any = {}) {
|
||||
return new Person(source);
|
||||
}
|
||||
|
||||
constructor(source: any = {}) {
|
||||
if ('string' === typeof source) {
|
||||
source = JSON.parse(source);
|
||||
}
|
||||
|
||||
this.name = source['name'];
|
||||
this.parent = Person.createFrom(source['parent']);
|
||||
this.details = anon1.createFrom(source['details']);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export class anon1 {
|
||||
age: number;
|
||||
address: anon2;
|
||||
|
||||
static createFrom(source: any = {}) {
|
||||
return new anon1(source);
|
||||
}
|
||||
export class Person {
|
||||
name: string;
|
||||
parent: Person;
|
||||
details: anon1;
|
||||
|
||||
constructor(source: Partial<Person> = {}) {
|
||||
const { name = "", parent = null, details = null } = source;
|
||||
this.name = name;
|
||||
this.parent = parent;
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
constructor(source: any = {}) {
|
||||
if ('string' === typeof source) {
|
||||
source = JSON.parse(source);
|
||||
}
|
||||
static createFrom(source: string | object = {}): Person {
|
||||
let parsedSource = typeof source === 'string' ? JSON.parse(source) : source;
|
||||
return new Person(parsedSource as Partial<Person>);
|
||||
}
|
||||
|
||||
this.age = source['age'];
|
||||
this.address = anon2.createFrom(source['address']);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export class anon2 {
|
||||
street: string;
|
||||
|
||||
static createFrom(source: any = {}) {
|
||||
return new anon2(source);
|
||||
}
|
||||
export class anon1 {
|
||||
age: number;
|
||||
address: anon2;
|
||||
|
||||
constructor(source: Partial<anon1> = {}) {
|
||||
const { age = 0, address = null } = source;
|
||||
this.age = age;
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
constructor(source: any = {}) {
|
||||
if ('string' === typeof source) {
|
||||
source = JSON.parse(source);
|
||||
}
|
||||
static createFrom(source: string | object = {}): anon1 {
|
||||
let parsedSource = typeof source === 'string' ? JSON.parse(source) : source;
|
||||
return new anon1(parsedSource as Partial<anon1>);
|
||||
}
|
||||
|
||||
this.street = source['street'];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class anon2 {
|
||||
street: string;
|
||||
|
||||
constructor(source: Partial<anon2> = {}) {
|
||||
const { street = "" } = source;
|
||||
this.street = street;
|
||||
}
|
||||
|
||||
static createFrom(source: string | object = {}): anon2 {
|
||||
let parsedSource = typeof source === 'string' ? JSON.parse(source) : source;
|
||||
return new anon2(parsedSource as Partial<anon2>);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue