Typescript Projects in TFS

If you develop Typescript applications in projects using TFS as source code control, you need to take precautions to build or publish your web application.

As the .ts and .js files are related in a VS project (.csproj) in the form

<TypeScriptCompile Include="Scripts\Index.ts" />
<Content Include="Scripts\Index.js">
  <DependentUpon>Index.ts</DependentUpon>
</Content>

when you check-out the .ts file, the .js is automatically checked out. The DependentUpon clause is also responsible for displaying the two files as parent-child nodes in Solution Explorer.

However if you build and the .ts file has not been checked out, the Typescript compiler is unable to generate the .js file, as it is set read-only in the file system.

I know of two solutions to this problem:

The first (and probably simpler one) is to include the .ts file in TFS, but NOT the .js file. This is achieved by adding the .ts (and automatically, the .js) file in TFS, but reverting the Add operation for the .js file.

The other solution is similar to the one I sketched about 3 years ago, namely to run tf checkout before and tf checkin after invoking tsc.

By the way, you can ignore the .d.ts (definition) files in this scenario, as they do not generate .js files.

Typescript Support for JavaScript Libraries such as jQuery

Most JavaScript code relies on functionality implemented by the numerous JavaScript libraries and frameworks available, such as jQuery.

To use these libraries from Typescript, you can either create so-called ambient definitions for the JS library manually, or use existing Typescript definition files (extension .d.ts).

The TypeScript source code repository contains a jquery.d.ts in the /bin directory, and a definition file for jquery.ui can be found in /samples/warship. However, those samples need not cover the respective library completely.

This question on SO points us to the github repository DefinitelyTyped

TypeScript type definitions repository for popular JavaScript libraries.

The project aims to provide high quality definitions for the most popular libraries out there.

which lists about 50 definition files covering major JS libraries and frameworks.

Automatically Compiling TypeScript in Visual Studio

After a bit of experimenting with TypeScript, I found two ways to automatically compile .ts to .js so far.

The first way is to create a project of type “HTML Application with TypeScript” and edit your TypeScript files there. Compiling the project will automatically generate the corresponding JavaScript files.

The advantage of this approach is that all your TypeScript code is kept in a separate project from your ASP.Net or ASP.Net MVC project.

But how do you get the compiled JavaScript files into your web project?

One solution is to set the project’s output directory to the script directory of your web project, and in Configuration Manager define the build order to build the TypeScript project before the web project.

For this method to work, the .js files generates by the TypeScript project must be included in the web project to be published.

But how does the TypeScript project know how to invoke the tsc compiler for .ts files? Well, it says so in the .csproj file by defining a BeforeBuild target:

<Target Name="BeforeBuild">
  <Exec Command="&quot;$(PROGRAMFILES)\Microsoft SDKs\
     TypeScript.8.0.0\tsc&quot; @(TypeScriptCompile 
     ->'&quot;%(fullpath)&quot;', ' ')" />
</Target>

If you copy this block to your web project’s .csproj file (unload project, edit project, reload project), it should make your existing project compile .ts files before invoking the regular C# build.

An answer on SO also suggest an extension that compiles on save, but this only works in VS 2012.

Getting Started with TypeScript

After installing TypeScript in Visual Studio, you can get started either experimenting with sample code and starting from scratch, or, as in my case, by migrating existing JavaScript code to TypeScript.

It definitely helps if you browse through the TypeScript Language Specification (pdf) before you start.

Most likely your JavaScript code references libraries such as jQuery, etc., which can also be used from TypeScript by a mechanism called Ambient Declarations. The pdf gives a basic example for jQuery, which I extended to match the jQuery functions my code uses:

interface JQueryStatic {
    (query: string): JQuery;
    (any): JQuery;
    ajax(data: any);
    toJSON(data);
}

declare var $: JQueryStatic;

These two declarations define the (“ambient”) jQuery variable $ as implementing the JQueryStatic interface with the functions listed.

The JQuery interface is another ambient declaration that I extended from the sample as:

interface JQuery {
    text(content: string);

    dialog(data: JQueryDialog);
    dialog(command: string);
    dialog(any);

    val();
    children: () => JQuery;
    remove();
    append(HTMLOptionElement);
    val(any);
}

The jQuery.dialog() function can be called with various parameter sets. $(“dialog-id”).dialog(“command”) passes a command to the specified dialog, whereas $(“dialog-id”).dialog({}) initializes a dialog.

One note on the dialog() declaration: as long as I declare JQueryDialog as interface, the code raised no compilation errors if only the first two signatures are declared. However after I changed it to a class, the line

$("#myDialog").dialog({
  modal: true,
  width: "540px",
  etc...
});

raised the error message

Supplied parameters do not match any signature of call target:
Could not apply type ‘string’ to argument 1, which is of type ‘{ modal: bool; width: string; buttons: { Ok: () => void; }; open: () => any; }’

In TypeScript, method overloading must include a method signature that matches all other signatures, so I added the dialog(any) declaration, and the code compiled again.

Please note that function overloading only works on declaration level – it has no effect on the generated JavaScript code. While multiple signatures are supported, there is only one implementation.

Installing TypeScript in Visual Studio 2010

After my lengthy introduction on how I finally got interested in developing in JavaScript and in the promises of TypeScript, here is how to install TypeScript in Visual Studio 2010.

The TypeScript homepage only refers to installing TypeScript in VS 2012, and the MS download page states

TypeScript for Visual Studio 2012 will install when Visual Studio 2012 is not installed, and provide the TypeScript compiler.

However, this answer on SO indicates a solution for VS2010:

  • Download the installer package (most current is TypeScriptSetup.0.8.0.msi)
  • Run the installer package to install the TypeScript compiler
  • Extract the .msi using 7zip
  • Copy or rename the extracted TypeScriptLS.vsix_File to TypeScriptLS.vsix
  • Run the .vsix file
  • The installer states it will install TypeScript support for VS 2010
  • (Close and) Open Visual Studio 2010

After successful installation, Visual Studio provides:

  • a new project type named “HTML Application with TypeScript”
  • a new item type named “TypeScript File”

If you do not find the new types immediately, simply type “Type” in the search box of the Add New dialog.