Struggling to create a directive with controller using Angular 1.5 and TypeScript 1.8, but it's not working out as expected. Despite closely following examples, the code just won't cooperate. Is there some sort of curse at play here?
Let's take a look at the code:
export class FooController implements angular.IController {
static $inject = ['myService', '$state'];
constructor(private myService: Services.MyService, private $state: angular.ui.IStateService) {
}
public foo: Services.Dtos.Foo;
public bar;
$onInit() {
if (!this.foo) return;
this.bar = this.$state.href('app.bar', {id: this.foo.id});
}
}
export class FooDirective implements angular.IDirective {
public restrict = 'E';
public replace = true;
public scope = {};
public templateUrl = 'content/templates/foo.template.html';
public controller = FooController;
public controllerAs = 'ctrl';
public bindToController = {
foo: '<',
};
}
The error is triggered in FooDirective
and presents the following issues:
- Class 'FooDirective' incorrectly implements interface 'IDirective'.
- Types of property 'bindToController' are incompatible.
- Type '{ foo: string; }' is not assignable to type 'boolean | { [boundProperty: string]: string; }'.
- Type '{ foo: string; }' is not assignable to type '{ [boundProperty: string]: string; }'.
- Index signature is missing in type '{ foo: string; }'.
What could be going wrong here?
UPDATE 2017/02/15 IDirective definition extracted from angular.d.ts file:
interface IDirective {
compile?: IDirectiveCompileFn;
controller?: string | Injectable<IControllerConstructor>;
controllerAs?: string;
/**
* @deprecated
* Deprecation warning: although bindings for non-ES6 class controllers are currently bound to this before
* the controller constructor is called, this use is now deprecated. Please place initialization code that
* relies upon bindings inside a $onInit method on the controller, instead.
*/
bindToController?: boolean | {[boundProperty: string]: string};
link?: IDirectiveLinkFn | IDirectivePrePost;
multiElement?: boolean;
priority?: number;
/**
* @deprecated
*/
replace?: boolean;
require?: string | string[] | {[controller: string]: string};
restrict?: string;
scope?: boolean | {[boundProperty: string]: string};
template?: string | ((tElement: JQuery, tAttrs: IAttributes) => string);
templateNamespace?: string;
templateUrl?: string | ((tElement: JQuery, tAttrs: IAttributes) => string);
terminal?: boolean;
transclude?: boolean | 'element' | {[slot: string]: string};
}