my initial observations (long post)

Topics: General
Dec 28, 2012 at 1:46 PM

I have now been developing two projects with TypeScript and thought this would be a good moment to share some of my initial observations (just to get some discussion started):

+ Love the type system. And when generics are added, this is a easy way to add type info to to your code without sacrificing too much of the flexibility that JS has to offer. One of my favorite features is the fact that Interfaces and Modules are open.

+ The generated JS is so recognizable, that I sometimes bug-fix the JS code instead of the TS code. So this is definitely an advantage in figuring out why something goes wrong. I'm happy with plain JS debugging and don't even bother with generating source maps.

+ The TS compiler is fast (even more so realizing it is running on top of a JS engine) and this makes the run/fix/compile cycles very quick.

+ Having the JavaScript and HTML API in a separate declaration file, provides great flexibility to change something in there without having to hack the compiler itself.

- External file modules really need some work. Right now they are not convenient to use, mainly due to the module alias that you are forced to use when accessing one of its exported members. Please allow somehow to import module members into the current scope without having to use a prefix all the time.

- Enumerations should not compile to numbers, but use strings instead. But I believe this is already on the radar.

- You should be able to set member variables in the constructor signature, but not define them. It makes the code much harder to read if you  can define member variables at two different places. So the following approach (like Dart) seems to be nicer to me: 

 

private name:string; 
constructor(this.name) {}

- Compiler needs some attention. Sometimes it misses type errors or even generates invalid code. Difficult to reproduce, but there has been cases that the _this was not generated while it was being used. Also nested functions are not type checked the same way as normal functions. But I'm sure these are things that will be fixed on the way.


- HTML interface is bad!!! Not really a TS issue, but by exposing the HTML API in a typed manner it becomes more obvious. Too weakly typed,  requiring too many typecasts and too many properties on the global (window) namespace. I now understand why Dart is coming up with a new API. Of course a TS user library could do the same and wrap the native API into something nicer to use without introducing too much glue.


- One monolithic lib.d.ts file is not a good approach. Should be split into several files, so you can pick what aspect you want to include in your project. For example serverside development should not have the HTML API available by default or a web worker has only a subset of the full HTML available. But there are many more examples, so a more flexible approach would be nice.

And finally a non-technical observation:

- The Microsoft TS project team itself seems to be smaller and moving at a slower pace than say for example Dart. When I look at the changes made to the source repository and the number of people making these changes, they are only a few. The same is true when it comes to the interaction of the TS team with the community. Not saying this is necessary a bad thing, but it does leave the impression that this is not (yet) a strategic project for MS. 

Of course another reason could be that they are working hard behind the scene and not ready to share the results yet. But even then it would be nice to have more interaction between the MS team and the community.

 

So far my rambling for today.

// Peter

Dec 28, 2012 at 5:31 PM

Thanks for the thoughtful feedback Peter.  Really happy to see the pluses at the top of the list there :-)

Regarding some of the minuses

  • External modules: Yes, module confusion (including the internal/external distinction) is something we're very aware of, and is the source of much discussion internally.  We do have the constraints of wanting to be a 'natural fit' with existing implementations and future proposals (e.g. Node, RequireJS, and ES6), but can hopefully make some improvements in this space (nothing concrete yet).
  • Regarding enums compiling to strings and not numbers:  Can you expand on this?
  • "You should be able to set member variables in the constructor signature, but not define them": I'll let someone with more background on the discussions that went into the class syntax comment here, but I do sympathize on this point.
  • "Compiler needs some attention": Most of the issues you mention (_this not generated, nested function type checking, etc...) we do have bug/fixes for currently.  Please do log issues in the issue tracker for anything that needs attention that we appear unaware of - especially any incorrect codegen as these are top priority for us.
  • The DOM API.  No comment :-)  We're trying to keep the codegen and dependencies to a minimal, so provide a library to wrap any of this is not in plan right now.  Other libraries (and their TypeScript typings), such as jQuery, Q, etc... hopefully provide some relief here.
  • Monolithic lib.d.ts: Yes, we're aware of this.  Options here are being discussed.  In the meantime, you can edit your own lib.d.ts, and if you reference this (with the same filename) we don't use the default one.
  • Team engagement: We are a relatively small team (relative being relative of course :-) ), and this time of year we have many folks out, slowing our responses even further, but we do aim do respond promptly to feedback, iterate quickly on new features, and also intent to make better use of our blog (http://blogs.msdn.com/b/typescript/) going forward.

 

Thanks again for the great feedback!

Dec 28, 2012 at 9:05 PM

Thanks for the quick reply, I guess you just prove me wrong about the TS team not being fully engaged with the community ;)

For the bugs, I'll open a ticket, although often they are almost impossible to reproduce in some isolated code fragment. 

With the enums they compile to numbers, right? So the first listed enum value gets the value  0 and so on. When you assign an enum value to a variable, you basically assign a number to that variable. This solution is great for comparison/ordinality, but not so nice when debugging JS code or dealing with them in the JS space. It would be nicer if they would be strings (or perhaps even real objects). So enum could be generated as:

enum Test { 
 FOO1, 
 FOO2
}

var Test;
(function (Test) {
 Test._map = {};
 Test._map["FOO1"] = 0;
 Test.FOO1 = "FOO1"; 
 Test._map["FOO2"] = 1;
 Test.FOO2 = "FOO2";
})(Test || (Test = {}));

Of course you would need some extra method to check for things like (Test.FOO2 > Test.FOO1), but for things like portability the above seems better than the current implementation.

// Peter

Dec 30, 2012 at 1:43 PM

@Peter,

Agree with you on a number of points. We don't use source maps either and it is crucial that the generated JavaScript be readable. We don't see things as being mature enough yet to the point where JavaScript simply becomes what IL is to C# - as a few others have been advocating on the forum.

 

The TS compiler is not fast from what we have experienced. I just ran rebuild on a solution containing 21 TypeScript projects - a total of about 130 TypeScript files, and that took 1 minute and 15 seconds. This is painfully slow - considering the number of times a rebuild is repeated over the course of a day's work.

 

Not very sure about the "this" in the constructor. Looks a bit foreign and the field has to be defined twice. I agree that having declarations in two places can be a source of confusion, but perhaps it is only a transitionary problem. I've caught myself scratching my head when searching for a missing private field, only to realise it had been defined in the constructor, but I believe it is only a matter of time before the grey matter has trained itself to follow the correct line of thought!

 

Regarding the bugs, these may be the ones being referred:

Missing _this: http://typescript.codeplex.com/workitem/181

Nested functions not being type checked: http://typescript.codeplex.com/workitem/450  (I believe this was a regression in TS 0.8.1)

 

Do agree that Microsoft need to throw more resources into this project. We (and I believe many others) now already have a lot of time and effort invested in migrating to and developing in TypeScript and we need to see bugs being fixed and released sooner than it is at present.

 

Noel

Dec 30, 2012 at 3:20 PM

@Noel,

Thanks for the references to the already opened issues, good to know that they are already worked on.

Regarding the performance of the compiler, we do indeed have a very different experience. In my case I compile 71 files within 3,5 seconds:

 

> time tsc @build

real 0m3.472s
user 0m3.068s
sys 0m0.184s

 

So that is very different from your experience. FYI, I'm building on an old Linux laptop and using solely external modules, it is a node server-side project (also the build file contains a list of all the TS files in my project). Would be interesting to see what causes this big difference in performance.

Regarding the declaration of properties in the constructor, I'm not sure yet. You might be right and it just takes some time to get used to a new way of working, time will tell. On the other hand the post-fix type annotation grew very quickly on me . But then again, this might be my old Turbo Pascal memories coming back to me from when I was a student ;)

 

// Peter

Dec 31, 2012 at 12:15 PM

 

I'm building in Visual Studio 2012. A Visual Studio TypeScript project works via a custom MSBuild task that executes tsc.exe, so that when the project is compiled the build task is executed, which in turn compiles all the TypeScript files in the project. The task looks like this:

 

  <Target Name="BeforeBuild">
    <Message Text="Compiling TypeScript files" />
    <Message Text="Executing tsc$(TypeScriptSourceMap) @(TypeScriptCompile ->'"%(fullpath)"', ' ')" />
    <Exec Command="tsc$(TypeScriptSourceMap) @(TypeScriptCompile ->'"%(fullpath)"', ' ')" />
  </Target>

 

As far as I know, this is the recommended way to compile TypeScript in Visual Studio. Also we do not use external modules, instead all files are referenced using the <reference> comment (since we are building a website and the external module pattern doesn't seem relevant).

I'm kind of beginning to see where the problem is: since it took 3.472 to run tsc.exe just the once, and I have 21 projects, that works out at 21 x 3.472 = 72.9 seconds or 1 minute 13 seconds, which agrees with the time I quoted of 1 minute 15 seconds.

It looks like there is a fixed overhead when tsc is run, so although we are both compiling a large number of files, in my case the times are much worse because tsc is being executed multiple times, which incurs the fixed overhead on every occasion.

If there is no fixed overhead (i.e. when compiling say 8 TypeScript files tsc.exe completes in less than 3 seconds) then I think that tsc (in my case) is compiling the same files multiple times. Since each project contains <reference> includes, it is most likely that these references are compiled anew for each project.

I wonder whether someone from the TS team is able to shed some light on this, and propose a solution?

 

Thanks

Noel

Coordinator
Jan 2, 2013 at 9:25 PM

Assuming I'm following the question (if not, let me know)...

One way to speed up compiles is to use the same kinds of tricks you would use in other compiled languages.  Namely, if your code is structured so that your various modules and classes depend on each other in clean, well-organized ways, then you should be able to use separate compilation techniques.

Each separately compiled section of code would have its own .d.ts file (which you can autogenerate using the --declaration compiler flag).  This is the file you'd reference from the other separately compiled code.  This prevents you from having to rebuild everything each time, though there is a little extra maintenance.