TypeScript¶
The ALFA TypeScript generator creates TypeScript files relating to the ALFA model definition.
The generated code depends on a single alfa.builtins.ts
file which is saved in the root of the namespace. This will be packaged
in future to avoid duplication.
Exporter Concepts¶
- All code relating to a single ALFA namespace is generated into a single TypeScript file.
- The generated code is plain TypeScript with no alignment to a library such as Angular, React or Vue.
- If UI specific features are required, they can be added as an extension to this generator, or a new type of generator.
- Main focus for ALFA TypeScript is to have type-safe, runtime validated JSON interchange supported code.
- Optional data types and other data type constraints will be checked for correctness before serialisation.
- To help code readability, even though TypeScript does not support the range of primitive types of ALFA, those have been defined
as type aliases. E.g.
type INT = number
. - Unlike other ALFA generated code, ALFA TypeScript generated code is mutable. This was done to avoid generating excessive code.
- All objects have accessor/mutator -
get*
,set*
methods. Theset*
method allow method chaining. All variables are private. - Currently ALFA record, enum, service, trait is supported in the code generator. Entity and union will be added soon.
- ALFA generic data types, compressed
, try and handful of other types are not yet supported, and will be added soon. - The supplied
JsonCodec
class supports converting to and from JSON compatible with other ALFA generated code ( Java, C#, Python ).
Exporter Example¶
Consider the following demo.alfa
definition. Lets look at what Java code is generated from this.
namespace Example
enum PropertyType {
Home
Office
}
service Updater( token : string ) {
getProperties() : list< Property >
saveProperty( a : Property ) : void
}
record Property {
HouseNo : int
Street : string
CurrentValue : double
ConstructedDate : date?
LocalAreas : list< Region >
}
record Region {
Name : string
}
This can be generated to TypeScript using the ALFA CLI - alfa -c -e typescript -o gen/java demo.alfa
or by setting
the exportType
to typescript
in the ALFA Maven Plugin.
The generated Java code is shown in the screenshot below.
import { JsonCodec, AlfaTypeFactory, AlfaObject, AlfaDescriptor,
TRY, SHORT, INT, DOUBLE, LONG, DURATION, TIME, URI, UUID, FLOAT, DATETIME, DECIMAL} from './alfa.builtin';
export interface Updater {
getProperties() : Array< Property >;
saveProperty(_a : Property) : void;
}
export interface UpdaterFactory {
create(_token: string) : Updater
}
export enum PropertyType {
Home,
Office
}
export class Property implements AlfaObject {
private _HouseNo: INT
private _Street: string
private _CurrentValue: DOUBLE
private _ConstructedDate: Date | undefined
private _LocalAreas: Array< Region >
getHouseNo() : INT {
return this._HouseNo
}
setHouseNo( v : INT ) : Property {
this._HouseNo = v
return this
}
getStreet() : string {
return this._Street
}
setStreet( v : string ) : Property {
this._Street = v
return this
}
getCurrentValue() : DOUBLE {
return this._CurrentValue
}
setCurrentValue( v : DOUBLE ) : Property {
this._CurrentValue = v
return this
}
getConstructedDate() : Date | undefined {
return this._ConstructedDate
}
setConstructedDate( v : Date | undefined ) : Property {
this._ConstructedDate = v
return this
}
getLocalAreas() : Array< Region > {
return this._LocalAreas
}
setLocalAreas( v : Array< Region > ) : Property {
this._LocalAreas = v
return this
}
toJSON() : object {
return JsonCodec.toJsonObject(this)
}
descriptor() : AlfaDescriptor {
return Property.__descriptor
}
static __descriptor = new AlfaDescriptor( "Example.Property", "record", {
// Removed for clarity
} )
}
export class ExampleTypesFactory implements AlfaTypeFactory {
private static types = {
"Example.Region" : Region,
"Example.PropertyType" : PropertyType,
"Example.Property" : Property
}
private static typeNames = new Set( Object.keys(ExampleTypesFactory.types) )
getAlfaTypeNames(): Set<string> {
return ExampleTypesFactory.typeNames
}
createInstance(alfaTypeName: string): AlfaObject {
let clz = ExampleTypesFactory.types[alfaTypeName]
return new clz()
}
}
Type Mappings¶
ALFA types are mapped to TypeScript with all numeric values being number and most other scalars being string. ALFA list, set and map are happed to TypeScript Array, Set and Map.
Example¶
The following is an example TypeScript code using the TypeScript above. It demonstrates an object being created, serialised and deserialised.
import {Property, Region, ExampleTypesFactory} from '../gen/Example'
import {JsonCodec} from '../gen/alfa.builtin'
let a = new Property()
a.setHouseNo(10)
a.setStreet("Main Street")
a.setCurrentValue(800000)
a.setConstructedDate(new Date(2010, 10, 30))
let areas = [ new Region().setName("NY"), new Region().setName("MT") ]
a.setLocalAreas(areas)
let json = JSON.stringify(a)
console.log(json)
let jsonObj = JSON.parse(json)
let n = new ExampleTypesFactory()
let decodedProperty = JsonCodec.toAlfaObject(n, jsonObj) as Property
console.log( "Year:" + decodedProperty.getConstructedDate().getFullYear() )
console.log( "Local area:" + decodedProperty.getLocalAreas()[1].getName() )
To execute the sample:
tsc -lib es6,dom Tests.ts
node Tests.js
The following output is produced.
{"$type":"Example.Property","HouseNo":10,"Street":"Main Street","CurrentValue":800000,"ConstructedDate":"2010-11-30","LocalAreas":[{"$type":"Example.Region","Name":"NY"},{"$type":"Example.Region","Name":"MT"}]}
Year:2010
Local area:MT