ngParty / ng-metadata

Angular 2 decorators and utils for Angular 1.x
https://hotell.gitbooks.io/ng-metadata/content/
MIT License
355 stars 46 forks source link

[Idea] angular 1 template type checking with TypeScript #105

Open reppners opened 8 years ago

reppners commented 8 years ago

Wouldn't it be super useful if we could do type checking on template code in angular 1?

Quick research shows I'm not the only one having that thought: https://github.com/Microsoft/TypeScript/issues/5151 https://github.com/Microsoft/TypeScript/issues/369 https://github.com/thorn0/babel-plugin-transform-ng1-jsx

I'm bringing this here because this project plans to have or already has a template parser and is having the @Input() and @Output() decorators which define the API of a component.

So right now I'm just having this initial thought and would like to discuss it with the community. If there are already other projects that are better suited as a "starting point" for this than please share them here.

Hotell commented 8 years ago

So that's interesting idea. Unfortunately all efforts you've linked have failed so far...

What is more doable IMHO is implementing propTypes like React has (runtime type checking)

There were some efforts to bring it to Angular core, but well didn't happen and won't happen as I see it... https://github.com/angular/angular.js/issues/11657

Or there is this nice library from Victor Savkin ( not Angular related ) https://github.com/vsavkin/RuntimeTypeChecks

What can be done with ng-metadata:

reppners commented 8 years ago

Thanks for pointing me to the runtime type check efforts, didn't know about these and they look very useful.

However runtime checks are only one part and I'm very interested in getting static support from the compiler or by using the typescript language services.

A naive approach could be:

I'm just brainstorming so I have no idea if there are any obvious roadblocks that I'm missing.

thorn0 commented 8 years ago

An approach alternative to JSX could be to create a type checker that would generate some TS code from the HTML templates. This code wouldn't be supposed to run, only to be type-checked. E.g.

<my-widget prop="$ctrl.foo()"/>

could be converted to something type-checkable like following

let myWidget: MyWidget; myWidget.prop = $ctrl.foo();

The type of $ctrl must be specified somehow in the template, e.g. with a special comment.

reppners commented 8 years ago

This code wouldn't be supposed to run, only to be type-checked. E.g.

Yes, this is the way I would've tried to make it happen.

The type of $ctrl must be specified somehow in the template, e.g. with a special comment.

It is known already because of the nature of components. $ctrl is the component controller which is the starting point for the whole template type-check.

reppners commented 7 years ago

Just as a heads up: I'm working on this in my spare time. Got template-to-code transpiler basically working but did rely on TSLint as a kind of "runner" for it. This won't work in the long run because of its "single-file-scope" but was enough to get going and do experiments.

Also there are lots of special-cases down the road that need to be solved but I will publish what I have on github as soon as it can be applied to a project with the complexity level of a TODO-app ;)

EDIT: After refactoring a codebase of >150 components I wish it would be already working!

alecmerdler commented 7 years ago

Is there any progress on this feature @reppners? It would be awesome just to see what you had accomplished and try and work off of it. I am actively refactoring our AngularJS codebase as well, and the majority of bugs so far have been template-related.

thorn0 commented 7 years ago

BTW, I gave up on https://github.com/thorn0/babel-plugin-transform-ng1-jsx because TypeScript wasn't flexible enough at that time. However, it's not the case any longer. The big blocker has been removed. See https://github.com/Microsoft/TypeScript/issues/7004#issuecomment-263137934

emmanueltouzery commented 7 years ago

I wrote a project to handle this issue specifically for angular1 views. It uses the typescript compiler API to parse the javascript and typescript code, htmlparser2 to parse the views, and the parsimmon parser combinator library to parse angular expressions (such as "for .. in .. track by ..").

It then generates "viewtest" files, combining code from views and controllers, which then get type checked by the compiler at the same time as normal typescript files. It also allows the user to specify custom angular directives & filters to have them also type-checked.

Obviously it does not support everything possible with angular1, by far, as the scope is huge, but we use it on a real-size project at work, and tested it on another real-size one too.

You can find the project there: https://github.com/emmanueltouzery/ng-typeview