Convert from Javascript to Typescript - javascript

How would I convert this function from Javascript to Typescript?
var ToggleSwitch = this.ToggleSwitch || (function () {
//Code
}
I know the var ToggleSwtich part can be written as export class ToggleSwitch {}, but I'm not sure about the rest of the line.

If you write a module, you'll end up with nearly identical code...
module ToggleSwitch {
}
Modules can be extended in TypeScript. The only difference is the compiler will know whether the module is already declared or not, which saves you the test.
To take this example further, here is an example with ToggleSwitch declared twice, with different contents. You'll notice that you can access all the contents. This can be split across multiple files:
module ToggleSwitch {
export class a {
go() {
alert('a');
}
}
}
module ToggleSwitch {
export class b {
go() {
alert('b');
}
}
}
var a = new ToggleSwitch.a();
var b = new ToggleSwitch.b();
a.go();
b.go();

Typescript is supposedly a superset of Javascript, so inherently, any Javascript should be valid Typescript.

Because TypeScript is a superset of JavaScript, most valid JavaScript is valid TypeScript too. In this case, your code (after adding a missing parenthesis at the end) is valid TypeScript and valid JavaScript.

Related

Creating generic classes and functions in javascript ES06

I'm from java background. I use Generics in java in following way:
class ApiResponse<T> {
T data;
T getData(){
return T;
}
}
I'm unable to use generics in javascript ES06. I wanna know whether it's possible or not creating generic classes?
JavaScript is a dynamically typed language and it doesn't have any generics. You can write a normal function/method, it will work for all types.
P.S. Use Typescript if want to code like you do in Java.
How do you like this, Elon Musk? Pure js, no typeflow/typescript
class BaseClass {
hello = function () {
console.log('hello!');
}
}
function GenericClass(T, Base) {
return class extends Base {
field = new T();
}
}
class DerivedFromGeneric extends GenericClass(String, BaseClass) {
greet = function() {
this.hello();
console.log('greetings ', this.field);
}
}
let i = new DerivedFromGeneric();
Javascript in itself doesn't provide any syntax to support generic classes. But it's possible using:
Flow
or
Typescript
Let me show an example of using generic class using Flow in javascript ES06:
export class ApiResponse<T> {
data: ?T = null
}
You can use Typescript for this purpose.
https://www.typescriptlang.org/docs/handbook/generics.html
Javascript doesn't have strict typing so there is no need for Generics because all variables can be assigned to any type at any time.

Typescript Enums compiling into both d.ts and Javascript output

In my original TS file (foo.ts), I have this:
export const enum ACCESS_STATE {
master,
readonly,
none,
failed
}
After the Typescript compiler completes, the output (foo.d.ts) file properly contains this:
const enum ACCESS_STATE {
master = 0,
readonly = 1,
none = 2,
failed = 3,
}
However, the resulting output (foo.js) file has no reference to ACCESS_STATE or its values at all. This isn't a problem in foo.js directly, since the compiler would have properly substituted the ACCESS_STATE.master and other references to the hard value of 0 (etc).
The problem is that I have other javascript modules that require foo and want to reuse the enum.
Is it possible to have the compiler generate something in the foo.js that is referenceable and can be used ? Such as:
var ACCESS_STATE = (function () {
function ACCESS_STATE () {
this.master = 0;
this.readonly = 1;
this.none = 2;
this.failed = 3
}
return ACCESS_STATE ;
}());
foo.ACCESS_STATE = ACCESS_STATE ;
Why is this not the default behavior of the compiler to generate a re-useable kind of thing that can be a referential substitute for the values in the enum (which is what is generally intended by using an enumeration)?
From the documentation:
Const enums can only use constant enum expressions and unlike regular
enums they are completely removed during compilation.
To have enum code in javascript, you need to remove const from export const enum. Alternatively, you can compile your code with --preserveConstEnums option.

Calling JavaScript function inside a JavaScript module from TypeScript v2.2.1

I've a JavaScript module in this way
myJSModule.js
var myJSModule = function () {
var _public_ = {};
_public_.foo = function () {
}
return _public_;
}();
Now I need to call it in a function in TypeScript
myTypeScript.ts
namespace Custom {
export function foo111() {
myJSModule.foo(); // error: "Symbol myModule can't be properly resolved"
}
}
What's the correct way to call foo in myJSModule?
The best way is to use an ambient declaration. You can make the ambient declaration in your TypeScript file, but it is often easier to manage if you place them in separate .d.ts files.
In your case you might add a file called myJSModule.d.ts:
declare var myJSModule: {
foo(): void;
}
This will tell the compiler that myJSModule exists, and has the described type.
Here's one possible solution thanks to the comment of #Jared Smith
I can cast the window object to any so I don't need to declare an interface.
myTypeScript.ts
namespace Custom {
export function foo111() {
(<any>window).myJSModule.foo();
}
}
For more information read the article http://ourcodeworld.com/articles/read/337/how-to-declare-a-new-property-on-the-window-object-with-typescript
You can just declare the module
declare const myJSModule : any;
namespace Custom {
export function foo111() {
myJSModule.foo();
}
}
If you have a definition file of the JS module you can also add it to your ts configuration.

Create type definition for method exposed on namespace

I'm converting an existing JavaScript application to Typescript. I start with:
// file1.js
(function(ns) {
ns.bar = function() { };
}(window.MyNamespace || {}));
// file2.js
(function(ns) {
ns.Item = function() {
this.doStuff = function() { ns.bar(); };
}
}(window.MyNamespace || {}));
Now I'm converting file2.js to TypeScript:
module MyNamespace {
class Item {
doStuff() {
MyNamespace.bar(); // This is obviously a problem
}
}
}
There is a problem with calling bar. I understand that converting file1.js to TypeScript will make things a lot easier, but that file is quite large in reality so I want to do the conversion next sprint and get a intermediary situation.
How do I solve that? How do I tell tsc that bar is a function on the module itself?
I've tried declare var bar: () => void; inside the module and variations thereof, but didn't get it to work so far.
I know I could consider converting those "namespace-functions" to static methods on a class, but that would require rewriting file1.js now, which I don't want (yet).
I've got a workaround like this:
module MyNamespace {
var ns: any = MyNamespace;
class Item {
doStuff() {
ns.bar();
}
}
}
But that feels a bit off, not in the least because it requires changes inside my class, whereas I'd prefer to have a bridge between file2.ts and file1.ts seperate from the final file2.ts stuff.
In essence, I feel like I'm writing a .d.ts file for my original file1.js functionality that will make file2.ts work now, in a way that can remain unchanged after converting file1.js to .ts.
Any tips? How do I create a typing for my unconverted file1.js?
Add a declare statement next to the module like this:
declare module MyNamespace {
var bar: () => void;
}
module MyNamespace {
class Item {
doStuff() {
MyNamespace.bar(); // This will compile!
}
}
}
You could (should) remove this temporary declaration of the bar method once you've converted file1.js to Typescript

creating typescript classes to work with existing Javascript and Backbone objects

I started working on a project where Backbone and Javascript are being used. I'm unsure how to start integrating Typescript. For example, we have a namespace of our company that precedes our views, models, objects, etc. So creating a backbone object would look like this without typescript:
Company.Views.MyNewView = (function () { return Backbone.View.extend({ } })();
So now, using Typescript, I thought I could do something like
class Company.Views.MyNewView {
}
However, Typescript doesn't like the period in the name. So my first question was how do I use Typescript with an existing namespace in my project? Those namespaces are simply defined as
var Company = Company || {};
Company.Views = Company.Views || {};
My second question is more general. Looking ahead, can Typescript easily integrate with an existing project where everything is defined with standard javascript? I'm not sure really how to access any of my non-Typescript class objects. Thanks in advance.
Edit:
Attempt to integrate with existing Javascript objects
declare module Company.Views {
export class MyNewRouter extends Company.BaseRouter {
// It does not recognize Company.BaseRouter
}
}
Typescript has the concept of modules. A module is effectively equivalent to Company || {}.
So you can do the following :
module Company{
export module Views{
export function MyNewView(){
return <any>Backbone.View.extend({ });
}
}
}
Which compiles into :
var Company;
(function (Company) {
(function (Views) {
function MyNewView() {
return Backbone.View.extend({
});
}
Views.MyNewView = MyNewView;
})(Company.Views || (Company.Views = {}));
var Views = Company.Views;
})(Company || (Company = {}));
A simpler example
The following typescript:
module Company{
// You need to do at least one export
// for compiler to generate any code
export var foo = 123;
}
generates:
var Company;
(function (Company) {
Company.foo = 123;
})(Company || (Company = {}));
For integrating existing JS
You need to create declarations for typescript to know about your Js. Js doesn't care if you declare a variable in one file and use it in another. TypeScript does since it needs to do compile time checking.
The simplest declaration is :
declare var SomeJSStuff:any;
And you can build up from there.
For the second part the following is how you would do it:
// Declare your JS stuff
declare module Company {
export class BaseRouter {
// Additionally declare any memebers of BaseRouter
// e.g:
someProp:number;
}
}
// Now use your JS Stuff in typescript
module Company.Views {
export class MyNewRouter extends Company.BaseRouter {
// It recognizes Company.BaseRouter
}
}

Categories

Resources