Martin Brabec
Martin Brabec

Reputation: 3840

Structuring of TypeScript files and code in ASP.NET project

So I'm working on this ASP.NET (.NET 4.6, VS2015), which has all business logic writen in C#. But since it is not just presentation web, there will be a lot of logic on the client as well. So I took TypeScript as it looked like a great tool which will help me organise my client-side code with a style I'm used to from C#.

However, as I'm diving deeper and deeper, I see that TypeScript is nothing like C#. It all relates to a single problem:

TypeScript does not support simple class-per-file (or interface-per-file etc.) rule, where you could simply include several classes (interfaces..) in another file.

This would really come in handy, since I want to define my ViewModel classes and initialization scripts for each page, where I would use all of these models and utils.

Personaly, I found two "solutions"

A: Keep class-per-file rule and wrap each in a namespace like this:

// Analogy to c# using
import utils = App.Code.Utils;

namespace App.Code {
    export class ZipCodeValidator {

        public zipCode: string;

        public validate(): boolean {
            // I can use class from another 
            let stringValidator: utils.StringValidator = new utils.StringValidator();

            // TODO validation
            return true;
        }
    }
}

This solution I took from start and I was very happy with it. Until I found out that sometimes the order of compiled files is wrong. Yes, I can manualy keep referencing other files (or use _references.ts), but for me its like going back several years. I'm going to have hunderts of files (thanks to my class-per-file rule).

Also "they say" I can generate js files by namespaces, which is also great advantage so I can create files general.js, app.js and admin.js (you know what would be used where).

B: Second solution is to "properly" use Modules. As I understnad it, I can write it like this:

import { StringValidator } from "./Utils/StringValidator";

export default class ZipCodeValidator {
    public zipCode: string;

    public validate(): boolean {
        // I can use class from another 
        let stringValidator: StringValidator = new StringValidator();

        // TODO validation
        return true;
    }
}

But this means I need to import every single class manualy. Despite the fact that intellisense does not work properly using this approach, if I omit the "default" keyword, I also need to specify each class manualy. Also, I don't know about any posibility on how to separate source into different js files based on directory.

Ok, you may say that I misunderstood TypeScript. It is all about modules, right? But I will not settle with "you need to define all your classes in one module". Thats just not right. I could stay with JavaScript then.

PROBLEM with A: I need to manualy keep track of all files and maintain their correct order.

PROBLEM with B: I need to import all class by class. Solution would be if I could do something like

import * as utils from "./utils/"

But as far as I understand, this is not possible.

Summary

Could you please give me a push to the right track? Some tool, maybe some plugin or anything? I like TypeScript and I want to use it. I just refuse to do manual work in these days. I hope this question will help other guys like me.

Thanks

Upvotes: 2

Views: 863

Answers (1)

hagner
hagner

Reputation: 1050

The way I do it is to use approach B and use modules. I then collect all the common modules in a wrapper module where I re-export them for easy importing in other modules.

An example:

AllUtils.ts

export * from './UtilClass1';
export * from './UtilClass2';
export { UtilClass3 as SomethingElse } from './UtilClass3';

This will allow use to use a single import statement to import all your classes like this:

import * as utils from './AllUtils';

let myUtil = new utils.UtilClass1();

Intellisense works for me in VS2015 using this approach. Added benefit of this is that you can omit or rename certain classes in the re-export. You will still have to add them one by one into the wrapper file but this will only have to be done once.

Upvotes: 3

Related Questions