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).