TypeScript or Babel?

So everybody is focusing on Babel, but to me it seems like typescript is a better option:

  1. Typescript should be a superset of javascript, so it should be like babel + more

  2. It’s true that Babel claims a better ES.Next support, but if you check case by case TS is almost always on par, eventually with small workarounds

  3. Typescript has better backing, seems like a more reliable option

  4. Type annotations are useful

  5. TS is easier to setup

  6. TS seems to have the lead on popularity

So why everybody picks babel over TS? Is it true that TS has feature parity with stage1/stage0 babel?

For me, there is two reasons:

  1. TypeScript is cool, if your IDE supports its type-awareness. I tried Webstorm, but this IDE was way to slow for me. So I ditched it, and Atom is not really an IDE.

  2. Babel is based on the ECMAScript standard, whereas TypeScript is somewhat proprietary. Good, but still proprietary. And with these languages, you never know where they are heading at in the future. Same goes for CoffeeScripts. So I decided to stick to standard tech, even if it’s not as nice as TypeScript.

Personal preference, I think.

Yes, it’s so proprietary, it doesn’t even have a publich GitHub repository…

… oh, wait.

But surely it still has a license with massive hooks and drawbacks

Apache License

Oh.

2 Likes

@rhywden I have been meaning to give that a stab sooner or later but I could not find a concise yet complete overview of the whole meteor typescript experience.

It sounds like you are using it in production. So would you mind sharing your overall experience, perhaps along with some pointers, gotchas, goodies etc?

Thanks!

1 Like

@serkandurusoy I’ve had 3 days off work, and I took this opportunity to:

  1. Read this. It’s poorly written, but it gets you going.

  2. Cover what you still don’t know with this.

  3. Then port some server only imports folder to npm package, written in TS.

This way Meteor doesn’t know about typescript, you can practice safely with the language, and you focus your effort where it is most effective, as server side code usually holds the biggest cognitive complexity.

1 Like

Great! Thank you very much!

Edit:
Thank you for those links and especially pointer 3!

Although, I’m kind of interested in typescript mileage strictly within Meteor projects. Meteor has globals, symbols hidden away in core or atmosphere packages, methods etc.

So how well does all that play with typescript?

Or you can do what I did:

  1. Install the barbatus:typescript package https://github.com/barbatus/typescript

and then simply begin to use Typescript. Using React is also possible and only needs a single entry in a config file.

If you want to use Meteor stuff with typescript, you need definition files. You could, of course, write those yourself but no one does that.

There are three ways to get such definition files (besides rolling your own):
a) Use npm - you simply do this: npm install --save react @types/react
b) Use typings - that’s a helper program which pulls down definitions from several sources (like npm or DefinitelyTyped)
You can search for definitions with typings search react and then install them with typings install --save --global dt~react
The dt~ part indicates the source - if you want npm sources you do npm~
Install typings through npm install -g typings
c) If no such file exists, then you can do the following for npm-modules:

npm install -g dts-gen
npm install -g module_without_typings
dts-gen -m  module_without_typings

which will automatically create a typings file for you (however, most types will be defined as any)

If you don’t want to do all that you can also always do: declare module "foo"; which short-circuits TypeScript and lets you write anything, basically.

What you shouldn’t do: Mix the @types/module and typings methods - both can have different update levels which can lead to new and interesting problems.

2 Likes

can I ask you something @rhywden ?

I’m trying to create a simple class. The generated JS works, it works in TS, but not on ts-node

index.ts
`

export class SheetApi {

    hello = () => 'hello world';

}

`

in REPL:

$ import {SheetApi} from './sheetApi'
'use strict'
$ SheetApi
⨯ Unable to compile TypeScript
[eval 10].ts (1,1): Cannot find name 'SheetApi'. (2304)
$ 

what am I doing wrong? Is it a problem with ts-node? everywhere else works

Well, I’m not an expert. But my first instinct would tell me that you’re exporting Api and trying to import SheetApi.

lol that was a typo :stuck_out_tongue: :stuck_out_tongue: :stuck_out_tongue: the original source is ok

Not sure what is happening on your end. Over here, this is working perfectly fine:

1 Like

Thanks @rhywden for the thorough run down. I’m especially happy with the “what you shoudn’t do” part. That’s the kind of gem I was looking for.

Well, you can certainly do that.

But from my experience the npm sources seem to have issues which sometimes result in either something breaking (when you mix dt~ and npm~) or at least give you an annoying warning every time there’s a reload even though your code is perfectly fine.

1 Like

I’ll certainly keep that in mind. BTW, are you aware of any Meteor-TypeScript-React boilerplate or decent open source app I can take a peek at?

If you don’t mind throwing redux into the mess, you can take a look at what I did:

Clone the repo, do npm install and you’re pretty much set. I tried to keep the mysterious code stuff out of there, save for one thing:

In https://github.com/Rhywden/nawischule3/blob/master/imports/client/store.ts you’ll find this:

const composeEnhancers =
    process.env.NODE_ENV !== 'production' &&
    typeof window === 'object' &&
    (<any>window).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?   
      (<any>window).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
      }) : compose;

That’s intended for the Chrome Browser AddOn Redux DevTools. However, if you don’t have that it’ll work just fine.

1 Like

Well that’s certainly immensely helpful, thank you for sharing it. I will certainly give it a shot. :pray:

Edit:
I’ve took a peek at it and I like what I see. I was kind of reluctant about setting this thing up for the client and thinking I would be better of with typescript on the backend and not the ui, but it seems it is not that scary and might indeed even be quite helpful. Thank you for this.

I’ll now risk acting like a spoiled child here and go ahead and ask you if you also have something of a boilerplate for the backend as well? You know with the usual suspects such as a collection, a, schema, publication, method etc. :slight_smile:

Not yet. I’m only starting out as well. But it really shouldn’t be any different than client-side.

I’m probably a little more curious about schemas if anything. I’m now
pondering a proper ORM (something similar to astronomy but based on simple
schema validations) and how typescript would fit into that picture.
Probably well, but I’m also probably overthinking.

In case you’re interested in using alanning:roles, this is the definitions file I just whipped up. No guarantees, but it should work.

declare module Roles {
    function addUsersToRoles(users:string|Array<string>, roles:string|Array<string>,group?:string):void;
    function createRole(role:string):string;
    function deleteRole(role:string):void;
    function getAllRoles(): Mongo.Cursor<{}>;
    function getGroupsForUser(user:string|Meteor.User, role?:string):Array<string>;
    function getRolesForUser(user:string|Meteor.User, group?:string):Array<string>;
    function getUsersInRole(role:string|Array<string>, group?:string, options?:any): Mongo.Cursor<{}>;
    function removeUsersFromRoles(users:string|Array<{_id:string}>|Array<Meteor.User>, roles:string|Array<string>, group?:string);
    function setUserRoles (users:string|Array<{_id:string}>|Array<Meteor.User>, roles:string|Array<string>, group?:string );
    function userIsInRole(user_id:string, role: string, group?:string): boolean;
}

declare module "meteor/alanning:roles" {
    module Roles {
        function addUsersToRoles(users:string|Array<string>, roles:string|Array<string>,group?:string):void;
        function createRole(role:string):string;
        function deleteRole(role:string):void;
        function getAllRoles(): Mongo.Cursor<{}>;
        function getGroupsForUser(user:string|Meteor.User, role?:string):Array<string>;
        function getRolesForUser(user:string|Meteor.User, group?:string):Array<string>;
        function getUsersInRole(role:string|Array<string>, group?:string, options?:any): Mongo.Cursor<{}>;
        function removeUsersFromRoles(users:string|Array<{_id:string}>|Array<Meteor.User>, roles:string|Array<string>, group?:string);
        function setUserRoles (users:string|Array<{_id:string}>|Array<Meteor.User>, roles:string|Array<string>, group?:string );
        function userIsInRole(user_id:string, role: string, group?:string): boolean;
    }
}

simply include that as, for example, alanning-roles.d.ts somewhere in /imports

Now I just have to see who I have to talk to to get that included into DefinitelyTyped or something.

I remember a discussion here on the forums to start a community effort to get meteor related type definitions into a common repo or wherever they are publicly shared. Hmm…