Skip to content

Syntax Error when Decorator mutates original Entity #7687

Closed
@sebald

Description

@sebald

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    QuestionAn issue which isn't directly actionable in code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions