Visual Studio Error List: Ignore a JavaScript reference - visual-studio-2012

There are probably like three people doing what I'm doing but here goes:
Visual Studio 2012
Latest Web Essentials
TypeScript project
AngularJS framework
Running Chutzpah tests with Jasmine
When creating tests for Chutzpah, I need to add references not only to my typescript files but also to the javascript libraries that I'm using. For example:
// Typescript References (for tsc)
/// <reference path="../ref/angular-1.0.d.ts" />
// JavaScript references (for chutzpah)
/// <reference path="../lib/angular.min.js" />
// TS references for what we're actually testing...
/// <reference path="../src/modules.ts" />
With this setup, my typescript-authored jasmine tests are running great. However, the angular.min.js file is filling up my error list with hundreds of complaints. This makes it impossible to find errors that are reported by the typescript syntax checker.
If I remove the reference to angular.min.js, then Chutzpah cannot run since my code depends on the library.
Is there a way to force Visual Studio to ignore errors in a particular JavaScript file reference?

This issue is now solved in Chutzpah 2.4.
Chutzpah Specific Reference
With the addition of TypeScript support a few releases ago several
people reported issues when using Chutzpah with the TypeScript plugin
in VS. The problem occurs since both TypeScript and Chutzpah are using
the comments for different purposes. To get around
this issue Chutzpah now supports two ways to reference dependent
files.
The existing general way /// <reference path="foo.js" />
The new Chutzpah specific way /// <chutzpah_reference path="foo.js" />
Using the latter will let Chutzpah know about your dependency graph
and should not confuse the TypeScript compiler.

This is a bug with Chutzpah which the developer now appears to be aware of:
http://chutzpah.codeplex.com/discussions/404083#post1008911

The problem you have here is that you are including a .js file as a reference.
You should only be using .ts files as references.
Including the .js file is causing TypeScript to treat is as a typescript file, hence the errors.
Have a look on DefinetelyTyped and switch the angular.min.js to the Angular.d.ts file to allow for your TypeScript compilation to pass.

I had the same problem with jasmine tests needing /// comments in order to run. In my case they were needed because I'm using Resharper and want to be able to take advantage of their javascript test runner.
The solution (although, not ideal) is based on the discussion at http://typescript.codeplex.com/workitem/466. As of v9.1.1 typescript, the compiler ignores references that include a space after the '='. So, instead of using
/// <reference path="~/somefile.js"/>
You use this instead:
/// <reference path= "~/somefile.js"/>
Beware: this may break in future versions of Typescript, but, hopefully by then, the language will support a way to include references for javascript files that are ignored by the compiler.

Related

Why don't for..of loops over Iterables work when run within Jest?

I have the following TypeScript code:
const myMap = new Map([["name", 5]]);
for (const foo of myMap.values()) {
console.log(foo);
}
When I run this code in node (v8.12.0) directly, it works and prints out "5" to console.
If I run this exact same code in a Jest test, it never executes the contents of the for loop. It runs the for condition and then just skips past the loop, never actually enumerating the values.
Why is that? Is there something about the JS runtime used by Jest (isn't it node?) that doesn't support for..of over iterables?
Thanks!
After a very long investigation, I have gotten to the bottom of this. Important background information about the solution:
When targeting older ECMAscript versions like ES3 and ES5 with the TypeScript compiler, using for..of loops to iterate over Iterable collections is not supported by default. If you want to use for..of with Iterable, you have to either target something newer than ES5 or use the --downlevelIteration flag.
To use Jest with a TypeScript project, you use ts-jest. At least, I was. I think you can also use babel somehow but I think ts-jest is preferred.
When using ts-jest, by default it tries to use the tsconfig.json file that the project uses -- which, as far as I can tell, means the one that is next to the jest.config.js file you are using (or the current directory if you aren't specifying a jest.config.js file). If it cannot find a tsconfig.json file in the project directory, it uses the default TypeScript compiler options. The default compiler options cause the TypeScript compiler to target ES3 or ES5 (the ts-jest docs claim it defaults to ES3 but that ts-jest overrides the default in this case to be ES5). --downlevelIteration is not on by default.
With all this in mind, I was able to figure out that ts-jest was not able to find my project's tsconfig.json file and so it was running my tests using the default settings, which meant targeting ES5 and not allowing downlevelIteration, so all my for..of loops over Iterable didn't work. The reason it couldn't find my tsconfig.json file is because my jest.config.js file was in a different directory (higher up in the tree) and even though I was running jest from a directory with a tsconfig.json file, ts-jest was not looking in the "current" directory but was instead looking in the directory that I pointed jest at for my jest.config.js file, which did not contain a tsconfig.json.
My solution to this was to rework my directory structure a bit and leverage the tsConfig option of ts-jest to tell it where to find my tsconfig.json file, which made everything "magically" work since my tsconfig.json file targets es2018, which supports for..of iteration over Iterable.
One alternative solution I considered but quickly disregarded was feature of the aforementioned tsConfig setting to directly set the --downlevelIteration compiler option in the jest config. I chose not to do that because, while it would have fixed this specific problem, it would not have fixed the larger problem which is that my Jest tests were compiling my TypeScript with different flags than my production code! It just so happens that only current problem caused by this was my for..of loop misery.
A quick postscript: the way I eventually made headway on this issue is by stumbling across the diagnostics option in ts-jest. Once I set it to true, when I tried to run my tests, an error like this was displayed:
TypeScript diagnostics (customize using [jest-config].globals.ts-jest.diagnostics option): src/foo.ts:163:47 - error TS2569: Type 'Map<Guid, FooInfo>' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.
It seems like TS compiler errors should be displayed (and cause test failures) regardless of whether or not ts-jest "diagnostics" are enabled but shrug.

How do I write TypeScript tests that don't include the classes under test in the transpiled test code?

I have a TypeScript project that compiles down to a single JS file in /dist.
I have Jasmine tests, also written in TypeScript, that reference the various classes they test with references like:
/// <reference path="../../../src/script/classUnderTest.ts" />
When I compile the tests the TypeScript compiler pulls in all the referenced classes and I get a single JS file containing the test code and the code under test.
This actually works fine for just running the tests, but now I'd like code coverage too. From what I can tell, to get Istanbul to work I need to have the code under test separate from the test code. Also it would be nice to be testing exactly the JS file that will be live.
So, how can I get the type safety and autocomplete benefits of "/// reference" whilst using my compiled JS file when the tests are actually run?
(Or am I barking up the wrong tree entirely?)
Note, I am building this on a Mac, so from what I've read Chutzpah is not currently an option. I'm also currently using only npm scripts to do builds. I'd prefer to not bring in grunt or gulp unless it's absolutely necessary.
So, how can I get the type safety and autocomplete benefits of "/// reference" whilst using my compiled JS file when the tests are actually run?
Don't using TypeScript's --outFile option (few other reasons). Instead use modules e.g. --module commonsjs and a module loader e.g. webpack.
More
Browser quickstart : https://basarat.gitbooks.io/typescript/content/docs/quick/browser.html
Modules:
https://basarat.gitbooks.io/typescript/content/docs/project/modules.html

How to set up typescript 0.9.5 in Visual Studio 2012

I'm trying to write a game in Typescript but I am having a hard time setting things up.
I am using visual studio 2012 and I installed typescript 0.9.5.
What I want is to build an app/game like I would in C# or AS3, meaning using putting classes in seperate files and using modules to seperate/connect code. This would then compile to either a single file or some kind of require.js like solution (which I'm also not clear about).
But I have done a lot of research and ran in to a lot of hurdles.
-There are a lot of references to calling something like "tsc greeter.ts" but when I use this in the visual studio command window I get back "Command "tsc" is not valid." I tried adding the tsc folder to environment variables path, but this didn't change anything. So I can't really run it. Also I don't understand how tsc would know where greeter.ts is located.
-I'm confused between the "///" and the import statement. How do these factor in the structuring of an app?
-It seems there are a lot of ways to make a typescript app, which all have different requirements and code style and structure. Is there no standard way, or am I just mistaken and is there a good way to approach this?
So the main question is: How do I build a typescript app/game structured like a c# or AS3 app?
To answer just some of your question, you no longer need the /// reference like this:
/// <reference path="../typings/jquery.d.ts"/> This was used in earlier versions of typescript, however now it will find any typescript files in your project for you.
I don't think there is a 'standard' way to create a typescript project any more than there is C#, there are many design patterns and you will have to research the pros and cons of both and choose one.
You should also no longer need to run "tsc greeter.ts" to compile your code. It will compile on build of the project.

How to create a TypeScript Nodejs module spanning multiple files

I'm trying to create a Node.js module with a single namespace using TypeScript. I need the classes of the module to be in separate files, and have references to each other. I also need this module to utilize other node modules. But if I understand right, TypeScript only supports namespaces if a namespace is contained within a single file or the namespace does not use external modules.
Some people present the use of post-build tools to make the final module work, which is nice but doesn't address all the errors TypeScript throws when combining cross-file namespaces and imports during development.
Is it true that the closest solution is to create a module per file, and create a web of inter-imports?
I find that what works best for me for module dependencies is to always use source references, e.g.:
/// <reference path="other.ts" />
Since you can't generate single-file output from tsc if you use language-level imports/modules, I have resorted to using require as a function and so on.
This seems to be the same solution chosen by the TypeScript developers themselves (search for "require(" there). As suggested by silentorb's comment, you can declare the require function as some variation of the following (or use DefinitelyTyped):
declare function require(name: string): any;
Note that there's often a lot of discussion on the whole modularity topic in TS over on the TS forums (one recent example).

Customizing the specific output files for various Typescript input files

I've got a web project using TypeScript that has some reasonably complex requirements for the compiled output files. So for instance, I need all the *.ts files in one directory to compile down to one single .js file, and all the *.ts files in another directory to compile down to a different .js file. (It's more complex than that, but you get the idea.)
I've been able to get this working using the tsc.exe command-line, using input files and what-not, but I'd like to be able to use MSBuild .targets files - among other things, using tsc.exe from the command-line seems to be pretty poorly supported on continuous integration servers, where it can be located who-knows-where, and certainly isn't likely to be in the path.
According to this answer here, it seems like I should be able to do this using custom build targets. So I've created a custom version of Microsoft.TypeScript.targets, and in addition to the default "CompileTypeScript" target, I've created a second one, "PayboardApiV10", so that the relevant part looks like so:
<Target Name="CompileTypeScript" Condition="'$(BuildingProject)' != 'false'">
<Message Text="Compiling TypeScript files normally" Importance="high"/>
<VsTsc
ToolPath="$(TscToolPath)"
ToolExe="$(TscToolExe)"
Configurations="$(TypeScriptBuildConfigurations)"
FullPathsToFiles="#(TypeScriptCompile)"
YieldDuringToolExecution="$(TscYieldDuringToolExecution)"
OutFile="$(TypeScriptOutFile)"
OutDir="$(TypeScriptOutDir)"
>
<Output TaskParameter="GeneratedJavascript" ItemName="GeneratedJavascript" />
</VsTsc>
</Target>
<Target Name="PayboardApiV10" Condition="'$(BuildingProject)' != 'false'">
<Message Text="Compiling TypeScript files for Payboard API v1.0" Importance="high" />
<VsTsc
ToolPath="$(TscToolPath)"
ToolExe="$(TscToolExe)"
Configurations="$(TypeScriptBuildConfigurations)"
FullPathsToFiles="#(TypeScriptCompile)"
YieldDuringToolExecution="$(TscYieldDuringToolExecution)"
OutFile="Payboard.js"
OutDir="$(ProjectDir)api\v1.0\"
>
<Output TaskParameter="GeneratedJavascript" ItemName="GeneratedJavascript" />
</VsTsc>
</Target>
And then I've specified a "CustomTool" in my project configuration for the specific files that I'd like to get picked up by the "PayboardApiV10" build target, like so:
I should note that I have no idea if I'm doing this bit correctly. I can't seem to find any documentation on it, and the only examples I've been able to find are from that previous answer. And more to the point, when I run my builds, all the TS files in my project get caught up in the first build target, including the ones for which I've specified "MSBuild:PayboardApiV10" for the custom tool. The "PayboardApiV10" tool never seems to get run, i.e., I never see the message "Compiling TypeScript files for Payboard API v1.0".
So two questions:
(1) Is there a better way to do what I'm trying to do?
(2) If this is generally the right way to do it, any ideas as to what I'm doing wrong?
The direction you're going is the optimal way (on save). In the meantime you can use post-build events to transform the typescript. Right click on your project and select properties. Select Build Events and in the Post-Build area you can specify command line parameters to use tsc.exe.
On the direction you're going (compile on save) I think the project file may be missing the following on each file you want compiled:
<TypeScriptCompile Include="app.ts" />
The configuration is also likely missing the environment settings.
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<TypeScriptTarget>ES5</TypeScriptTarget>
<TypeScriptIncludeComments>true</TypeScriptIncludeComments>
<TypeScriptSourceMap>true</TypeScriptSourceMap>
</PropertyGroup>
More information on both methods is available at this TypeScript wiki page.
I ended up asking this same question over on the TypeScript forums (https://typescript.codeplex.com/discussions/455781). The conclusions I drew from the conversation there:
There isn't a great way to do it now.
The best hacky way to do it now is probably the way that I was doing it, namely, with batch files, post-build events, and checking the compiled files into source. Other folks recommended Grunt, or the ASP.NET MVC bundling mechanism (the latter won't work in my scenario); I've also used the r.js minifier in the past. And these will work; but to reiterate, none of these are really very good solutions.
The best way to do it in the future will be to create "library projects" of TypeScript files, so that all TS files in a given project get compiled together; and then you can reference the library TS projects from your main Web project, and will automatically get the compiled files merged into your main ~/Scripts folder. But that will require support from the TS team - which Jon Turner basically indicated would be coming, though he didn't say when. (See also https://typescript.codeplex.com/workitem/571.)

Resources