Getting TypeScript to Work with a LightSwitch HTML Project (kind of)

Last week I saw a post on the LightSwitch forum that pointed out that steps outlined in a blog post by Michael Washington regarding using TypeScript in a LightSwitch project were no longer working. So I thought I would go through the blog post and try it out. I hadn’t done anything with TypeScript before so this was my first experience. The steps outlined in Michael’s blog post definitely didn’t work anymore and it ended up taking me a while to figure out how to get things “working” (in air quotes), so I figured I’d post about it.

To start, here’s a brief summary of the issues I ran into:

  • There was no entry in the “Add” context menu for “TypeScript File” when right-clicking on the HTMLClient project (i.e. the .jsproj)
  • There was no entry for “TypeScript File” in the “Add New Item” dialog
  • When I added a new JavaScript file and renamed it to end with a .ts extension, I couldn’t get the .ts file to compile and generate the corresponding .js file (I tried a variety of different things here that I won’t get into)

I did find an open bug that was something along the lines of “TypeScript should work with JavaScript projects (.jsproj)” so hopefully these will all be addressed in the near future.

Here is what I needed to do to get things to work:

Close VS

Find the .jsproj file in the HTML sub-project’s folder and open it with Notepad

image

Insert the bolded entries just below the first PropertyGroup node near the top of the file:

 

<PropertyGroup Condition=" '$(Configuration)' != 'Release' ">
  < UseDesignTimeFeatures>true</UseDesignTimeFeatures>
< /PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
< TypeScriptTarget>ES5</TypeScriptTarget>
< TypeScriptRemoveComments>false</TypeScriptRemoveComments>
< TypeScriptSourceMap>true</TypeScriptSourceMap>
< TypeScriptModuleKind>AMD</TypeScriptModuleKind>
< /PropertyGroup>
< PropertyGroup Condition="'$(Configuration)' == 'Release'">
< TypeScriptTarget>ES5</TypeScriptTarget>
< TypeScriptRemoveComments>true</TypeScriptRemoveComments>
< TypeScriptSourceMap>false</TypeScriptSourceMap>
< TypeScriptModuleKind>AMD</TypeScriptModuleKind>
< /PropertyGroup>
< Import Project="C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\TypeScript\Microsoft.TypeScript.targets" />
< Import Project="C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\TypeScript\Microsoft.TypeScript.jsproj.targets" />

<PropertyGroup Label="Globals">

I stole this snippet from a new TypeScript project that I had created and after some spelunking online found various sources that said that these are the meaningful parts regarding JavaScript generation (I changed the Import nodes to use absolute paths instead of environment variables because it didn’t work with the environment variables on some machines). Note that you need to remove all the leading spaces in front most of the elements (LiveWriter insists on adding these during the publish process, sorry).

 

Open your LightSwitch project in VS and choose to add a new JavaScript file to the HTMLClient project

image

 

Change the name of the file to end with .ts instead of .js

image

 

Paste this code into the file that was just created (this is taken from Michael’s blog post)

 

 class FormatName {
    _firstname: string;
    _lastname: string;
    _age: number;
    constructor(
        firstname: string,
        lastname: string,
        age: number
        ) {
        this._firstname = firstname;
        this._lastname = lastname;
        this._age = age;
    }
    ReturnName() {
        var formatedName =
            this._lastname.toUpperCase()
            + ", " +
            this._firstname.toLowerCase()
            + " {" + this._age.toString() + "}";
        
         return formatedName
       }
}

 

Then save the file. Now what should have happened is that a .js file was generated and added to the .jsproj. The .js file is created, but it isn’t added to the project

image

 

image

So, we need to manually add this to the project by performing Add >> Existing Item and selecting the .js file from the browse window that opens

image

 

Now the .js file will be copied out to the Scripts folder when you do a build. Finally, you will need to add an entry in the HTMLClient project’s default.htm to include this new file

<script type="text/javascript" src="Scripts/Generated/generatedAssets.js"></script>

<script src="scripts/formatname.js"></script>
<script type="text/javascript">

After all this, we now have generated JavaScript that we can call from the JavaScript files that are generated when you “Add Code” to a screen. Here’s an example (again taken from Michael’s blog). This example is for the “postRender” code for a List (notice the lines using FormatName and ReturnName).

 myapp.BrowsePeople.rows_render = function (element, contentItem) {
    // Write code here.
    var itemTemplate = $("<div></div>");
    var FirstName = contentItem.data["FirstName"];
    var LastName = contentItem.data["LastName"];
    var Age = contentItem.data["Age"];
    var objFomatName = new FormatName(FirstName, LastName, Age);
    var FinalName = $("<h1>" + objFomatName.ReturnName() + "</h1>");
    FinalName.appendTo($(itemTemplate));
    itemTemplate.appendTo($(element));
};

So that is something, not much, but something. We got some good feedback on the forums about ways we could improve the experience for supporting TypeScript from a LightSwitch project. Hopefully we can deliver on some improvements in the future.

A sample project for the sample described here can be found at https://code.msdn.microsoft.com/Using-TypeScript-with-c418131a