Reputation: 10372
My TypeScript and plain JavaScript code need to share a namespace and some data. TypeScript should "prepare" a namespace, external JS provides data, TypeScript processes it.
The context is an Angular 2 application. The loading order is:
Currently in the external JavaScript file I'm doing something like this:
if (typeof Blog === 'undefined')
{
Blog = {
Posts: []
}
}
// ...
Blog.Posts.push(post);
In my Angular 2 app this JavaScript file is being dynamically loaded and the value then accessed like this:
declare var Blog: any;
...
let firstPost = Blog.Posts[0];
This works, I can access data placed by the external JS.
Now I want to keep the JavaScript part as minimal as possible. So I want to move the declaration of Blog
and Posts
to TypeScript, preferably so that it can be used there in a strongly typed fashion.
So I wish my JavaScript looked like this:
// ...
Blog.Posts.push(post);
Note the missing declaration of Blog
. I tried something like this in TypeScript:
declare var Blog: BlogClass; // <- this is probably wrong, can be changed to anything necessary to make it work...
// ...
Blog = new BlogClass();
But apparently its not that easy. My Angular 2 app dies on me with a generic error message. The error is caused by Blog = new BlogClass()
.
Any hints on how to solve this?
Upvotes: 0
Views: 1271
Reputation: 51579
declare
means that the thing being declared must be defined somewhere else.
declare var Blog: BlogClass;
does not produce any code in the resulting javascript, so this assignment
Blog = new BlogClass();
fails at runtime because Blog
does not exist.
When you remove declare
, this line appears in the generated code:
var Blog;
However, it does not necessarily create var Blog
in global scope - when you compile typescript code as modules, it will be created inside a module and will be inaccessible to external javascript code, unless you go through the route of exporting it from typescript module and importing that module in your javacsript code.
The simplest (but a bit dirty) way to make sure that an object is created in global scope is to do that explicitly:
(window as any).Blog = new BlogClass();
Upvotes: 2