Core: Typescript Branch

Created on 30 May 2018  路  19Comments  路  Source: adonisjs/core

Hi there. Recently I've started to push forward typings here: https://github.com/thisdotvoid/adonisjs-types. However, two things bother me:
1) if we use "use" function, we have to make monkey patching adding export{} otherwise TS will throw "cannot redeclare block-scoped variable" . If we use es6 import or require() , then we just lose code completion, because we including .js file. And Typescript's allowJs works bad if .js lives in node_modules. There is so much more to write about this, I've tried so many ways, but none of them is elegant and working at the same time.
2) typings is an additional maintenance overhead - once source changed, typings are obsolete/broken and must be changed too.

After fighting for long hours for few days, for me there is only option that left: source code of Adonis must be written in TS, as files with .ts extension. I,ve already started to try this locally, and it works very well.

Now what I am going to do: fork, transform js extensions to ts, write required ts types, class fields, etc. And write some doc section about typescript. What is important, Adonis will still be usable by those who do not know/use/like typescript.

Now my question: @thetutlage is it ok? What can you say before I start? Hopefully you just say OK, but that OK should mean that you have made thoughtful decision. Thanks

Most helpful comment

Hi @anurbol 馃憢

Code-base is currently being rewritten for V5 in TypeScript.

All 19 comments

Hi @anurbol 馃憢

Code-base is currently being rewritten for V5 in TypeScript.

@anurbol Seems like you have spent some good time researching on how to add intellisense in AdonisJs. I did same and found that Valid Javascript is Typescript is not 100% true.

I decided to re-write bunch of stuff in Typescript and our reasons can be different. For me Intellisense or atleast VsCode is not important than the ease of using AdonisJs.

What I am not doing

  1. I want, Adonis to work like a charm with Javascript. However, you can opt in to use Typescript.
  2. The standard modules of Node.js should work fine, without any transpilation.
  3. I am not making changes in the public API of Adonis, just to make Typescript happy.

Why I am using Typescript

  1. For automated API docs via Typedoc.
  2. Improve intellisense, if I can without sacrificing the charm of Adonis.

Thanks for the quick answers!
@RomainLanz, that's a good news! However, I failed to find corresponding branch or commits. If it's currently being rewritten, then where it is happening? I mean, is it done locally? Is the job just at the very-very beginning (done locally on your computer), so there is no single commit yet? Or is it now just a stage of discussion, if yes then where (I haven't found one on github and gitter)? Or is everything just in our heads still :D

@thetutlage
"I decided to re-write bunch of stuff in Typescript" - Same questions as above, is it just only decision, that exist at the moment? Which is also totally makes me happy, because that decision is key thing, other is matter of time/code. I even tracked your activity, and I noticed you are currently working on Edge template system, using TypeScript though, that's great. If you are going to start re-writing main library, then when it is going to happen? If not soon, can I start it now (in fork), without fear that you or someone already has done some fraction of work (e.g on your computer) and we'd have conflicts? If fork is not acceptable, maybe branch is a way to go (better, because others will see it and participate)?

I totally agree with you on all points, and happy that you push exactly all mentioned by you principles, I just was slightly confused by this sentence, and not sure what you mean: "For me Intellisense or atleast VsCode is not important than the ease of using AdonisJs" - ease of using AdonisJS for me (and maybe others) definitely is a good code completion (intellisense), instead of learning docs/API. I really feel old and tired of hundreds of documentations that I have to read again and again. I want to give you good example of reason of my motivation :
I started to migrate my migrations (sorry my wordplay) from Laravel to Adonis. I see, while main principles are the same, there is new API, new method names like notNullable() instead of nullable(false). Reading docs, or even diving into source code is exhausting, I just want to migrate as quick as possible and continue developing business logic. Instead of investigating API/docs, I've installed typings (even in their current, far from perfect realisation) and got code completion, so I quickly (seconds rather than minutes) see that new method is notNullable. Also, chance of mis-typing is next to none, I see which methods are chainable and what they return, etc. My long-term memory and mental capacity freed for business logic and other tasks, which is key for effectiveness. I hope you include this case in concept of "ease of using".

All the other points, I totally agree with them:
1. I want, Adonis to work like a charm with Javascript. However, you can opt in to use Typescript.
Yes, only thing that'll change, is that source files would contain not only .js files but also .ts (but .js files would be compiled, non-human-readable)

2. The standard modules of Node.js should work fine, without any transpilation.
I see no single reason why they'd break. No transpilation (e.g. babel, webpack, i do not love them frankly) would be used, only TypeScript compilation .ts => .js

3. I am not making changes in the public API of Adonis, just to make Typescript happy.
No one single change. Again, I see no reasons why this can happen.

P.S. other 2 cents:
I have strong belief, that some deep, incapsulated libraries and classes of main library (adonis/framework) do not need to be rewritten, only those which we use during developing app (e.g. Lucid), at least at the start.

Found this: https://github.com/adonisjs/discussion/issues/62 but it hardly answered my questions. Please let me start work on TS ASAP, if there is no conflicting current work, because, firstly, I have to migrate fast, and secondly, I do not even want touch things in bare JS (I have physical headaches from it), even despite the fact that code of Adonis is written really, I mean really well (thanks to that, converting it to TS seems easy).

@anurbol

Yes, no public work has started with Typescript on AdonisJs. I started with Edge to see how the tooling works and how helpful Typescript will be for the end user.

For me Intellisense or atleast VsCode is not important than the ease of using AdonisJs

By this I mean, Intellisense doesn't work 100% when your project is written in Javascript, even though type definitions exists. For example

const Route = use('Route')

I don't think in a Javascript project, the Intellisense will be able to guest the type of use('Route').

Also what makes Javascript great is it's dynamic nature. So I have to give up all the dynamic stuff, just to make Vscode happy, then ofcourse I am not doing it.

For example: You can add macros to Request and Response classes. The macros are added at runtime

Request.macro('username', function () {
  return this.input('username')
})

and you can use the macro as any other method on the Request object. So again I am not sure if Intellisene will be able to detect username as a method on Request class.

@thetutlage

I don't think in a Javascript project, the Intellisense will be able to guess the type of use('Route')
:D Easy! In fact it already works with https://github.com/anurbol/adonisjs-types/blob/develop/index.d.ts (scroll to the very end and you'll understand how it works) though previous author made it bit over-complexified, below I provide simpler example:

Your example with Request.macro is handle-able with TS same way:

declare class Request {
    static macro(what:'username', callback: () => string) : MacroClassOrWhatever
    static macro(what:'another_thing', callback: () => string) : MacroClassOrWhatever
}

more here: https://www.typescriptlang.org/docs/handbook/functions.html ("Overload" section). declare class is not real class, it is just additional description of _existing_ class.

Those things are exactly why people love TS (I used to hate it too)

Well, from your answer I concluded that there is no work started. That means I can start it by forking? What you think about creating TypeScript branch? I really want to complete this work in a week. Maybe 2 days if I will have luck. Maybe 2 weeks though, if not. I mean, it should not take so much time, so that many conflicts between branches would arise before finishing. I am not big OSS expert, though, so direct me.

Well I am starting today anyway. When something will be ready, I'll update status here and request comments.

Ohh nice examples. Yeah I am not much into Typescript, so still playing around, getting myself familiar and using it in Edge.

Yes, you can fork any repo you want and I will create a typescript branch and you can create PR against that branch.

Good! Let's begin :-) I'll try my best: https://github.com/anurbol/adonis-framework/tree/typescript

Hi everyone

Sorry if I get it wrong, just wanna clear it out: In order to use Adonis v5 we will have to use Typeccript?

Nope, it will work as it does right now

@PazzaVlad no, as thetutlage said absolutely nothing changes in API (no one gonna notice any changes or change how they work), it is only about tooling and code completion for Typescript users

@thetutlage Hi! Should I make pull requests incrementally after each step completed, or should I make many pull requests at once when everything is ready?

For now, lucid types are ready at that point when you can use migrations with .ts extension, enjoying full code completion, including chained methods. See https://github.com/anurbol/adonis-lucid/commits/ts
peek 2018-06-03 15-14
You see, now I don't have to open docs every 2 minutes or learn it. I am absolutely confident that I wrote method correctly without looking to them docs and without executing migrations to ensure that they work.

In the screencast I replaced use() method with import, but it can also be used, though shouldn't (at least in TS workflow), there are some problems with it, I can explain if you want.

What I plan next is:
add TS support for routes, controllers and models
add docs about enabling and using TS.
(quite complex one) add option to generate migrations, controllers, models with TS extension (and corresponding minor syntax differences). I though about this, how to do it the best way: easy for TS users and hidden from JS users, I think TS users should have command e.g. adonis ts:init, which creates config/typescript.ts. That file have something like:

{
  generateTsFilesFor: {
    migrations: true,
    controllers: true,
    models: true,
  }
}

So when user runs e.g. adonis make:model, cli should parse that config and generate files with correct extension.

What do you think (do not forget question at the beginning pls)?

@anurbol This looks awesome :)

I believe, we can do it incrementally inside a new branch, so it will be easier to track the changes and also simple for you to work incrementally on it.

I have created a typescript branch in Lucid and framework repo. Feel free to create a PR anytime

Thanks for the response! Great!!

@anurbol https://github.com/tiansin/adonis-quick-start-typescript
An interim solution, the application code using the typescript to write the code, then use auxiliary definition file to realize automatic.
I put all the typescript code in the src directory, the directory structure should be consistent with the application file structure, so the compiled files can link up.

@tiansin Its a shame that I failed to think of this solution. Great one

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

blendsoft picture blendsoft  路  3Comments

dezashibi picture dezashibi  路  4Comments

aligoren picture aligoren  路  4Comments

umaams picture umaams  路  3Comments

seanc picture seanc  路  4Comments