Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
reppners opened this issue Jun 17, 2016 · 8 comments
Open

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

reppners opened this issue Jun 17, 2016 · 8 comments
Labels

Comments

@reppners
Copy link
Contributor

reppners commented Jun 17, 2016

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:
microsoft/TypeScript#5151
microsoft/TypeScript#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
Copy link
Member

Hotell commented Jun 17, 2016

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... angular/angular.js#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:

  • we can incorporate typescript types for @input() and run the type check within the binding evaluation with option to turn those off, because perf issues, when running in production via enableProdMode()

@reppners
Copy link
Contributor Author

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:

  • parse component template, getting all the component tags used in the template
  • resolve the inputs/outputs of each found component tag
  • get the matching typescript component code
  • utilize the compiler API to see if there is an error both in bound controller properties/methods and in the utilized api of other components/directives

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

@thorn0
Copy link

thorn0 commented Jun 20, 2016

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
Copy link
Contributor Author

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
Copy link
Contributor Author

reppners commented Sep 16, 2016

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
Copy link

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
Copy link

thorn0 commented Apr 19, 2017

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 microsoft/TypeScript#7004 (comment)

@emmanueltouzery
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants