-
Notifications
You must be signed in to change notification settings - Fork 13.1k
Description
I wrote decorators (for Angular 1.x) to have some cleaner syntax when defining a component and using the DI.
The @Component decorator (see below) will mutate the original class in such a way that it will conform the ng.IComponentOptions type (when created). The original class will be "attached" to the controller attribute, etc.
So the decorator basically wraps the class inside another class from type Component. The resulting Component can be used to register itself with Angular (see below). The other decorator called @Inject will add meta data ($inject property) to the original class, so the DI will still work when the code is minified.
In the below example I am importing and creating a SomeComponentController, which is decorated with @Component and @Inject. The TS compiler will show a syntax error, because the imported component is not called with any arguments. But since the Component type doesn't require any, it is fine. Angular will inject the correct dependencies when it instantiates the controller (SomeComponentController).
It looks like a hard problem for the compiler to infer all this information, but is there a way to let it know that everything is fine? :) Because compiling and running the code works finde. Only the editor is not satisfied with the code.
TypeScript Version:
1.8.9
Code
import { Component, Inject } from '../utils/decorator';
import SomeService from '../services/some/some.service';
const template = require('./template.html');
@Component({
template,
bindings: {
input: '>'
}
})
@Inject('SomeService')
export default class SomeComponentController {
constructor( SomeService:SomeService ) {
// ...
}
}import * as angular from 'angular';
import SomeComponent from './some.component';
export default angular
.module('app', [])
.component('someSome', new SomeComponent()); // TS2346: Supplied parameters do not match any signature of call target.export function Component (config:IComponentDecoratorOptions):ClassDecorator {
return (target:FunctionConstructor) => {
const component = class Component implements ng.IComponentOptions {
public transclude:boolean | string | {[slot: string]: string} = config.transclude || true;
public template:string|FunctionReturn<string> = config.template;
public controller:FunctionConstructor = target;
public bindings:{[binding: string]: string} = config.bindings || {};
public require:string | string[] | {[controller: string]: string} = config.require || null;
};
return component;
};
}Expected behavior:
No error. Compiler recognizes the mutation.
Actual behavior:
Editor (vscode) shows "TS2346: Supplied parameters do not match any signature of call target." error.
But compiling the code actually still works without any errors (via webpack).