- ASP.NET Core MVC
- ASP.NET Core logging with Serilog
- ASP.NET Core managed config
- ASP.NET Core MVC with /api/-area
- ASP.NET Core API versioning
- ASP.NET Core API with Swagger UI
- ASP.NET Core EF in separate project
- ASP.NET Core AutoMapper
- ASP.NET Core response cache
- ASP.NET Core memory cache
- ASP.NET Core TypeScript

Using TypeScript in a similar style as C# to replace JavaScript on client side of MVC.
Background
The JavaScript ecosystem is full of libraries, frameworks and patterns. What is considered the best framework is a matter of taste, and seem to change often. “Flavor of the month” is a term often used.
In the end I just want to get things done, and I am neither impressed by or interested in adding a layer of client side MVVM framework on top of the MVC framework I am already using.
Since JavaScript lacks a few features I associate with quality, I adopted TypeScript early on. TypeScript solved many of the issues I had with JavaScript. But to fully embrace it I must apparently use modules, and when I get into that stuff I quickly end up in debugging more than I like. Probably cool, but I just want to get stuff done.
So I have adapted a style of mirroring C# in TypeScript. I use class instances and interfaces. I also associate scripts with their cshtml counterparts. For type safety I use TypeScript definition files for each JS library I use.
Install
Prerequisite
You need NPM/Node.JS installed. This will handle installation of TypeScript definition files, as well as other libraries. You can install Node.js manually or by Visual Studio installer.
Behind proxy?
If your company uses proxy for outgoing requests you may have to change NPM settings, as well as tackle certificate issue. NPM has its own list of valid CA, so your companys MITM CA will probably not be valid. Instead of going through the trouble of inserting valid root for your organization into NPM you can turn off the validity check.
1 2 3 |
npm config set proxy http://proxy.company.lan:8080 npm config set https-proxy http://proxy.company.lan:8080 npm set strict-ssl false |
Install jQuery type definition
Set up a tsconfig.json by adding new file of type “TypeScript JSON Configuration File” to project root. You need to specify both outDir and rootDir for it to replicate Scripts directory structure.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ "compilerOptions": { "noImplicitAny": false, "noEmitOnError": true, "removeComments": false, "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "target": "es5", "outDir": "wwwroot/Scripts", "rootDir": "./Scripts" }, "exclude": [ "node_modules", "wwwroot" ] } |
You can use Package Manager Console to execute the following command, but every time you restart VS you need to change directory to web project first, i.e.:
cd Tedd.CoreWebExample.WebUi
1 |
npm install @types/jquery |
This creates node_modules folder in project and installs jQuery type definition.
Implement
First and foremost: Scripts/*.ts will be compiled into wwwroot/Scripts/*.js. So any TypeScript file you put into Scripts/-directory will end up in a corresponding subdirectory under wwwroot/Scripts.
I usually keep scripts in a folder structure mirroring views.
Scripts/Home/Index.ts
1 2 3 4 5 6 7 8 9 10 |
export class HomeIndex { constructor() { $("#button").click(() => this.buttonClicked()); } public buttonClicked(): void { $("#text").text("Button was clicked"); } } var homeIndex = new HomeIndex(); |
First thing to note is that jQuery’s $ is not strongly typed because we did the NPM installation. Second is that the layout here closely resembles C#. It’s a class that gets created immediately (last line), that hooks up events at stratup (constructor) and that exposes public methods.
Views/Home/Index.cshtml
Reference the JS-script:
1 2 3 |
@section Scripts { <script src="~/Scripts/Home/Index.js"></script> } |
Hint: You can do this by dragging .ts-file from Solution Explorer into text editor for cshtml-file. With our current setup it will resolve directories correctly.