0

As I see, from examples, written by developers of TypeScript, they use some kind of stubs, for interoperability with JavaScript:

declare module Backbone {
    export class Model {
        constructor (attr? , opts? );
        get(name: string): any;
        set(name: string, val: any): void;
        set(obj: any): void;
        save(attr? , opts? ): void;
        destroy(): void;
        bind(ev: string, f: Function, ctx?: any): void;
        toJSON(): any;
    }
    ...
}
interface JQuery {
    fadeIn(): JQuery;
    fadeOut(): JQuery;
    focus(): JQuery;
    html(): string;
    html(val: string): JQuery;
    show(): JQuery;
    addClass(className: string): JQuery;
    removeClass(className: string): JQuery;
    append(el: HTMLElement): JQuery;
    val(): string;
    val(value: string): JQuery;
    attr(attrName: string): string;
}

That's looks weird. Can I omit writing such stub and just use jQuery object and call it's methods? I expect, that it is possible, because TypeScript is a superset of JavaScript and if it's possible in JavaScript, it's probably should be possible in TypeScript too. What are best ways to cal JavaScript code from TypeScript?

Gill Bates
  • 14,330
  • 23
  • 70
  • 138
  • 1
    Guys, why do you downvote somebody for asking a question based on a misunderstanding! – Lodewijk Bogaards Jul 26 '15 at 16:28
  • 1
    I downvote whenever an answer can found by reading a Wikipedia article. [Compatibility with JavaScript](https://en.wikipedia.org/wiki/TypeScript#Compatibility_with_JavaScript) [Declaration files](https://en.wikipedia.org/wiki/TypeScript#Declaration_files) – thoughtrepo Jul 26 '15 at 17:04
  • You should never use declarations like you describe. These have already been done for you, just install them into your project with `tsd install backbone -save`. Or just import backbone as type `any` if you don't want to take advantage of types. – Martin Jul 26 '15 at 19:05
  • 1
    @mallison the question (are declarations necessary) is not answered by the Wikipedia article. – Lodewijk Bogaards Jul 27 '15 at 06:19
  • Fair enough, no, it doesn’t explicitly state that. However, it does explain what declaration files are, how types are handled in TypeScript, and the purpose of the `any` keyword. From that knowledge a person can come to their own conclusion. Providing a direct answer to that question without a proper explanation would do more harm than good. If I did explain, I would repeating half of the article on Wikipedia. I prefer to help people find their own answers if possible. That’s why I commented instead of answering. – thoughtrepo Jul 27 '15 at 12:49
  • @mallison Go downvote all answers that cites or refers to any kinds of documentation, books and other knowledge bases. – Gill Bates Jul 27 '15 at 16:10
  • Don't twist my words, that's not what I said. This is now a waste of time. – thoughtrepo Jul 27 '15 at 18:16
  • @mallison You just totally wrong - answers, that reproduces something that exists in documentation or wikipedia, are absolutely ok! Stop wasting your time, arguing for ridiculous unprovable point of view and remove downvote! – Gill Bates Jul 28 '15 at 06:39
  • Have a look at [What does "all legal JavaScript is legal TypeScript" mean?](https://stackoverflow.com/questions/41750390/what-does-all-legal-javascript-is-legal-typescript-mean) – Bergi Aug 18 '23 at 22:59

3 Answers3

2

They are not stubs, they are type declarations. Since javascript is untyped the types need to be added to the function and method signatures. Without these typescript is not able to help you do any kind of static analysis.

For example:

The confirm function opens a popup, asks you a question and depending if you hit 'ok' or 'cancel' you get a boolean value true or false. In plain old Javascript you can call the function like this:

var x = prompt(1 + 1) + "hello world";

This doesn't make sense, since prompt expects a string parameter and returns a boolean. Typescript helps by adding this declaration in the standard lib.d.ts:

declare function confirm(message?: string): boolean;

Because of this the code I have written above would cause a compilation error using the typescript compiler.

Lodewijk Bogaards
  • 19,777
  • 3
  • 28
  • 52
  • But types are optional in TypeScript. – Gill Bates Jul 26 '15 at 16:23
  • Yes, so if the prompt function was declared like this: `declare function confirm(message?);` (notice the lack of input and output types) then the compiler would accept the example I've given. – Lodewijk Bogaards Jul 26 '15 at 16:31
  • 1
    But is there option to omit type declarations at all and go without static analysis? – Gill Bates Jul 26 '15 at 16:33
  • 2
    Yes, it is called Javascript :) If you want just the ECMAScript6 you could go with Babel. Personally I think types are pretty awesome. – Lodewijk Bogaards Jul 26 '15 at 16:36
  • Types are awesome, but writing declarations for every library is not awesome. – Gill Bates Jul 26 '15 at 16:37
  • You also mix typescript and javascript. – Lodewijk Bogaards Jul 26 '15 at 16:41
  • 1
    Have a look at https://github.com/borisyankov/DefinitelyTyped. It is unlikely that you need to type anything (it's big!). Also if you do not use type declarations you can still call all the functions; then they are just untyped. – Lodewijk Bogaards Jul 26 '15 at 16:43
  • Additionally, if you are using a library that's not in DT, you can make placeholder for it by simply adding `declare var UnknownLibrary: any;` Then TS will ignore it, and you can create the full definition later if you want (and add it to DT so other developers can use it). – thoughtrepo Jul 26 '15 at 17:40
1

You may perfectly omit those declarations and produce valid Typescript code ; the point of these instructions is to add information about the return type of vanilla Javascript APIs, in order to benefit from the static type checking of Typescript. If you don't use them, everything you import from a plain JS library is assumed to return a value of type any, which Typescript can't check much about.

This practice is known as type declaration files and you may not need to write your own : there are hundreds of such declaration files available online for the most popular Javascript libraries.

ttzn
  • 2,543
  • 22
  • 26
1

TypeScript tries to prevent you from using a variable that doesn't exist. For example, if I only had this code in a .ts file:

$("#myElement").hide();

TypeScript would output that into the .js file; however, it would also throw a compile error telling me $ hasn't been defined. This is to help prevent me from making mistakes.

So when I use a JavaScript library, like jQuery, without first telling the compiler about the variables from the JS code (ex. $), the compiler will throw an error to tell me they aren't defined. This might actually be a mistake on my part... the compiler doesn't know because I haven't told it and it can't properly analyze JavaScript code to find out.

To fix this, I can go ahead and tell the compiler this isn't a mistake by at least defining an ambient definition with an any type:

declare var $: any;

Now there won't be an error in my .ts file because I've told the compiler that this variable exists outside of the TypeScript code and by defining it with the any type, I've told it that this variable can be used in any way (this is the optional static typing part of the language).

However, no type information on a variable is not preferable. It's easy to use it incorrectly because there's no constraint on the variable's use. To fix this, I could go on to describe a bit more about the type of $, but this type definition already exists and so I can just use tsd to install it into my application:

tsd install jquery

Then use the downloaded jquery.d.ts file in my application.

David Sherret
  • 101,669
  • 28
  • 188
  • 178