There are several changes in 3.4. In addition to porting all Saltaralle code (Serenity.Script.UI) to TypeScript, we've optimized code generated under ServerTypings.tt (or ServerTypings folder).
One of the changes is using const enums feature in TypeScript 2.4. Basically it makes the declared enum a syntatic sugar, e.g. there is no actual code for enum in generated .js file, and all references to enum members are converted to inline constants.
Our Row.ts files under ServerTypings.tt contains a class called Fields that lists names of fields available in those entities. We used const strings before:
锘縩amespace StartSharp.Administration {
export interface UserRoleRow {
//...
export namespace Fields {
export declare const UserRoleId: string;
export declare const UserId: string;
//...
}
[
'UserRoleId',
'UserId',
//...
].forEach(x => (<any>Fields)[x] = x);
}
}
Unfortunately a const string in TypeScript is not an inline constant like in some other languages. Whenever you reference one of these constants, in your Web.js file you get something like StartSharp.Administration.UserRoleRow.Fields.UserRoleId instead of just "UserRoleId". And, even if you don't reference any of these constants, your Web.js file contains all these field names. Even though we optimized that a bit, it wasn't optimal.
As now TypeScript 2.4 has a const enum feature, which we can use to simulate inline constants, now our rows are generated like this:
export declare const enum Fields {
UserRoleId = "UserRoleId",
UserId = "UserId",
RoleId = "RoleId",
Username = "Username",
User = "User"
}
This and several other optimizations in Row.ts, Service.ts and Form.ts files under ServerTypings, allowed us to drop MyProject.Web.min.js file size by almost %50 in some projects. It depends on number of entities you have, so your results might vary.
Once you update to 3.4, you might get some TypeScript errors, as const enums cannot be assigned to a variable like we used to do, e.g. in OrderGrid.ts:
protected createQuickFilters() {
super.createQuickFilters();
let fld = OrderRow.Fields;
this.shippingStateFilter = this.findQuickFilter(Serenity.EnumEditor, fld.ShippingState);
}
This is the error that you'll get:
(TS) 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment.
What you should do is, replace let fld = or var fld = with import fld = and move that line to just under namespace declaration:
namespace StartSharp.Northwind {
import fld = OrderRow.Fields;
//..
There are several places you should do this, after that it'll be fine.
Just a note, make sure you are using Typescript 2.4+. I was on 2.3 and couldn't figure out why I was getting this error.
enum declarations member initializer must be constant expression
Great! Thank you very much!
Wow!! I can't even imagine the effort to complete the porting of all Saltarelle stuff to Typescript!!
Thank you very much!
I'm on Typescript 2.5.3, Serenity 3.5.5 but when I look at my Administration.UserRow.ts file I can stil see something like:
export namespace Fields { export declare const UserId: string; // the old way
and there is no code in my project with the new syntax:
export declare const enum Fields // the new way
did I miss something? How to switch to the new code generation?
Thanks
You'll get new style after T4 transform
@volkanceylan Do you know what the import actually does in import fld = OrderRow.Fields; ? I have a different error, but this syntax seems to fix it.
Import assigns an alias to a type during compilation, which is erased in generated code.
Most helpful comment
Wow!! I can't even imagine the effort to complete the porting of all Saltarelle stuff to Typescript!!
Thank you very much!