**I'm submitting a ...** <!-- (check one with "x") --> - [ ] bug report - [ ] feature request - [x] design discussion <!--(Please do not submit support requests here - see above)--> TypeScript introduced a new strictness flag with TS 2.7 - https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#strict-function-types It makes typechecking for callback based APIs much stricter. For example: ```typescript function f(mixedArray: (string|number)[]) { mixedArray.map((x: string) => x.charAt(0)); } ``` only errors when --strictFunctionTypes is turned on. AngularJs has many callback based APIs, which will be checked at more strictly with the flag. Some real bugs will be exposed, but also it will start erring on many correct patterns. For example: ```typescript { require: 'ngModel' link: (...., controller: NgModelController) {...} ``` This is now an error because TS doesn't know that require and link are related. As written the typings require one handle the full spectrum of options in the link function `IController | IController[] | {[key: string]: IController}`. TS types are quite expressive and @gkalpak and I tried to write up some prototype of typings that are aware of the link between require and link: ```typescript interface IDirective<T extends string|string[]> { link?: (x: LinkT<T>) => void; require?: T; } type LinkT<T> = T extends string ? IController : T extends string[] ? IController[] : never; ``` But even with full conditional types, it is impossible to extend this for user-defined directives. So as plan B, I am going to contribute some nice type aliases to DefinitelyTyped ```type LinkFnControllerType = IController | IController[] | {[key: string]: IController}``` and propose the canonical solution to be writing the link function as: ```typescript link: (..., controller: angular.LinkFnControllerType) => { let myController = controller as MyControllerType; } ``` One added benefit is that there is an explicit 'as' cast to remind the reader to check with the 'require' and controller statements.