From 41a7127404b965dd1abeac2f0c5fd3522e4a3b90 Mon Sep 17 00:00:00 2001 From: Jonathan Park Date: Mon, 16 Dec 2013 17:17:39 -0800 Subject: [PATCH 1/5] updating angular resource and injector definitions --- angularjs/angular-resource.d.ts | 129 +++++++++++++++++--------------- angularjs/angular.d.ts | 28 +++---- 2 files changed, 83 insertions(+), 74 deletions(-) diff --git a/angularjs/angular-resource.d.ts b/angularjs/angular-resource.d.ts index f74f3eb44..f3a8870cd 100644 --- a/angularjs/angular-resource.d.ts +++ b/angularjs/angular-resource.d.ts @@ -1,7 +1,6 @@ // Type definitions for Angular JS 1.2 (ngResource module) // Project: http://angularjs.org -// Definitions by: Diego Vilar -// Definitions: https://github.com/borisyankov/DefinitelyTyped +// Definitions: https://github.com/daptiv/DefinitelyTyped /// @@ -19,10 +18,19 @@ declare module ng.resource { // that deeply. /////////////////////////////////////////////////////////////////////////// interface IResourceService { + + , U extends IResourceClass>(url: string, paramDefaults?: any, + /** example: {update: { method: 'PUT' }, delete: deleteDescriptor } + where deleteDescriptor : IActionDescriptor */ + actionDescriptors?: any): U; + >(url: string, paramDefaults?: any, + /** example: {update: { method: 'PUT' }, delete: deleteDescriptor } + where deleteDescriptor : IActionDescriptor */ + actionDescriptors?: any): IResourceClass; (url: string, paramDefaults?: any, - /** example: {update: { method: 'PUT' }, delete: deleteDescriptor } - where deleteDescriptor : IActionDescriptor */ - actionDescriptors?: any): IResourceClass; + /** example: {update: { method: 'PUT' }, delete: deleteDescriptor } + where deleteDescriptor : IActionDescriptor */ + actionDescriptors?: any): IResourceClass>; } // Just a reference to facilitate describing new actions @@ -42,65 +50,66 @@ declare module ng.resource { // PATCH (in other words, methods with body). Otherwise, it's going // to be considered as parameters to the request. // https://github.com/angular/angular.js/blob/v1.2.0/src/ngResource/resource.js#L461-L465 - interface IResourceClass { - get(): IResource; - get(dataOrParams: any): IResource; - get(dataOrParams: any, success: Function): IResource; - get(success: Function, error?: Function): IResource; - get(params: any, data: any, success?: Function, error?: Function): IResource; - save(): IResource; - save(dataOrParams: any): IResource; - save(dataOrParams: any, success: Function): IResource; - save(success: Function, error?: Function): IResource; - save(params: any, data: any, success?: Function, error?: Function): IResource; - query(): IResource[]; - query(dataOrParams: any): IResource[]; - query(dataOrParams: any, success: Function): IResource[]; - query(success: Function, error?: Function): IResource[]; - query(params: any, data: any, success?: Function, error?: Function): IResource[]; - remove(): IResource; - remove(dataOrParams: any): IResource; - remove(dataOrParams: any, success: Function): IResource; - remove(success: Function, error?: Function): IResource; - remove(params: any, data: any, success?: Function, error?: Function): IResource; - delete(): IResource; - delete(dataOrParams: any): IResource; - delete(dataOrParams: any, success: Function): IResource; - delete(success: Function, error?: Function): IResource; - delete(params: any, data: any, success?: Function, error?: Function): IResource; + interface IResourceClass> { + get(): T; + get(dataOrParams: any): T; + get(dataOrParams: any, success: Function): T; + get(success: Function, error?: Function): T; + get(params: any, data: any, success?: Function, error?: Function): T; + save(): T; + save(dataOrParams: any): T; + save(dataOrParams: any, success: Function): T; + save(success: Function, error?: Function): T; + save(params: any, data: any, success?: Function, error?: Function): T; + query(): T[]; + query(dataOrParams: any): T[]; + query(dataOrParams: any, success: Function): T[]; + query(success: Function, error?: Function): T[]; + query(params: any, data: any, success?: Function, error?: Function): T[]; + remove(): T; + remove(dataOrParams: any): T; + remove(dataOrParams: any, success: Function): T; + remove(success: Function, error?: Function): T; + remove(params: any, data: any, success?: Function, error?: Function): T; + delete(): T; + delete(dataOrParams: any): T; + delete(dataOrParams: any, success: Function): T; + delete(success: Function, error?: Function): T; + delete(params: any, data: any, success?: Function, error?: Function): T; } - interface IResource { - $get(): IResource; - $get(dataOrParams: any): IResource; - $get(dataOrParams: any, success: Function): IResource; - $get(success: Function, error?: Function): IResource; - $get(params: any, data: any, success?: Function, error?: Function): IResource; - $save(): IResource; - $save(dataOrParams: any): IResource; - $save(dataOrParams: any, success: Function): IResource; - $save(success: Function, error?: Function): IResource; - $save(params: any, data: any, success?: Function, error?: Function): IResource; - $query(): IResource[]; - $query(dataOrParams: any): IResource[]; - $query(dataOrParams: any, success: Function): IResource[]; - $query(success: Function, error?: Function): IResource[]; - $query(params: any, data: any, success?: Function, error?: Function): IResource[]; - $remove(): IResource; - $remove(dataOrParams: any): IResource; - $remove(dataOrParams: any, success: Function): IResource; - $remove(success: Function, error?: Function): IResource; - $remove(params: any, data: any, success?: Function, error?: Function): IResource; - $delete(): IResource; - $delete(dataOrParams: any): IResource; - $delete(dataOrParams: any, success: Function): IResource; - $delete(success: Function, error?: Function): IResource; - $delete(params: any, data: any, success?: Function, error?: Function): IResource; + interface IResource> { + $get(): T; + $get(dataOrParams: any): T; + $get(dataOrParams: any, success: Function): T; + $get(success: Function, error?: Function): T; + $get(params: any, data: any, success?: Function, error?: Function): T; + $save(): T; + $save(dataOrParams: any): T; + $save(dataOrParams: any, success: Function): T; + $save(success: Function, error?: Function): T; + $save(params: any, data: any, success?: Function, error?: Function): T; + $query(): T[]; + $query(dataOrParams: any): T[]; + $query(dataOrParams: any, success: Function): T[]; + $query(success: Function, error?: Function): T[]; + $query(params: any, data: any, success?: Function, error?: Function): T[]; + $remove(): T; + $remove(dataOrParams: any): T; + $remove(dataOrParams: any, success: Function): T; + $remove(success: Function, error?: Function): T; + $remove(params: any, data: any, success?: Function, error?: Function): T; + $delete(): T; + $delete(dataOrParams: any): T; + $delete(dataOrParams: any, success: Function): T; + $delete(success: Function, error?: Function): T; + $delete(params: any, data: any, success?: Function, error?: Function): T; } /** when creating a resource factory via IModule.factory */ - interface IResourceServiceFactoryFunction { - ($resource: ng.resource.IResourceService): ng.resource.IResourceClass; + interface IResourceServiceFactoryFunction> { + ($resource: ng.resource.IResourceService): IResourceClass; + >($resource: ng.resource.IResourceService): U; } } @@ -109,6 +118,6 @@ declare module ng { interface IModule { /** creating a resource service factory */ - factory(name: string, resourceServiceFactoryFunction: ng.resource.IResourceServiceFactoryFunction): IModule; + factory(name: string, resourceServiceFactoryFunction: ng.resource.IResourceServiceFactoryFunction): IModule; } } diff --git a/angularjs/angular.d.ts b/angularjs/angular.d.ts index 3b0599ac4..af897a962 100755 --- a/angularjs/angular.d.ts +++ b/angularjs/angular.d.ts @@ -127,15 +127,15 @@ declare module ng { // this is necessary to be able to access the scoped attributes. it's not very elegant // because you have to use attrs['foo'] instead of attrs.foo but I don't know of a better way // this should really be limited to return string but it creates this problem: http://stackoverflow.com/q/17201854/165656 - [name: string]: any; - - // Adds the CSS class value specified by the classVal parameter to the - // element. If animations are enabled then an animation will be triggered + [name: string]: any; + + // Adds the CSS class value specified by the classVal parameter to the + // element. If animations are enabled then an animation will be triggered // for the class addition. $addClass(classVal: string): void; - // Removes the CSS class value specified by the classVal parameter from the - // element. If animations are enabled then an animation will be triggered for + // Removes the CSS class value specified by the classVal parameter from the + // element. If animations are enabled then an animation will be triggered for // the class removal. $removeClass(classVal: string): void; @@ -143,12 +143,12 @@ declare module ng { $set(key: string, value: any): void; // Observes an interpolated attribute. - // The observer function will be invoked once during the next $digest - // following compilation. The observer is then invoked whenever the + // The observer function will be invoked once during the next $digest + // following compilation. The observer is then invoked whenever the // interpolated value changes. $observe(name: string, fn:(value?:any)=>any): Function; - // A map of DOM element attribute names to the normalized name. This is needed + // A map of DOM element attribute names to the normalized name. This is needed // to do reverse lookup from normalized name back to actual name. $attr: Object; } @@ -451,12 +451,12 @@ declare module ng { then(successCallback: (promiseValue: T) => IHttpPromise, errorCallback?: (reason: any) => any, notifyCallback?: (state: any) => any): IPromise; then(successCallback: (promiseValue: T) => IPromise, errorCallback?: (reason: any) => any, notifyCallback?: (state: any) => any): IPromise; then(successCallback: (promiseValue: T) => TResult, errorCallback?: (reason: any) => TResult, notifyCallback?: (state: any) => any): IPromise; - - + + catch(onRejected: (reason: any) => IHttpPromise): IPromise; catch(onRejected: (reason: any) => IPromise): IPromise; catch(onRejected: (reason: any) => TResult): IPromise; - + finally(finallyCallback: ()=>any):IPromise; } @@ -700,7 +700,7 @@ declare module ng { valueOf(value: any): any; } - + /////////////////////////////////////////////////////////////////////////// // SCEDelegateProvider // see http://docs.angularjs.org/api/ng.$sceDelegateProvider @@ -709,7 +709,7 @@ declare module ng { resourceUrlBlacklist(blacklist: any[]): void; resourceUrlWhitelist(whitelist: any[]): void; } - + /////////////////////////////////////////////////////////////////////////// // Directive // see http://docs.angularjs.org/api/ng.$compileProvider#directive From 72cc26150630924e0a3fc3f6caadf351f043a245 Mon Sep 17 00:00:00 2001 From: Jonathan Park Date: Mon, 16 Dec 2013 17:39:28 -0800 Subject: [PATCH 2/5] adding invoke inline annotated functions --- angularjs/angular.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/angularjs/angular.d.ts b/angularjs/angular.d.ts index af897a962..12742a531 100755 --- a/angularjs/angular.d.ts +++ b/angularjs/angular.d.ts @@ -793,6 +793,7 @@ declare module ng { annotate(inlineAnnotadedFunction: any[]): string[]; get (name: string): any; instantiate(typeConstructor: Function, locals?: any): any; + invoke(inlineAnnotadedFunction: any[]): any; invoke(func: Function, context?: any, locals?: any): any; } From 71e23deaddd6c11702cee0ac4a76a61150da0859 Mon Sep 17 00:00:00 2001 From: John Emau Date: Mon, 16 Dec 2013 19:03:37 -0800 Subject: [PATCH 3/5] added tests for new angular-resource generics signatures --- angularjs/angular-resource-tests.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/angularjs/angular-resource-tests.ts b/angularjs/angular-resource-tests.ts index 2b7c5c438..911267f15 100644 --- a/angularjs/angular-resource-tests.ts +++ b/angularjs/angular-resource-tests.ts @@ -1,5 +1,8 @@ /// +interface IMyResource extends ng.resource.IResource { }; +interface IMyResourceClass extends ng.resource.IResourceClass { }; + /////////////////////////////////////// // IActionDescriptor /////////////////////////////////////// @@ -14,9 +17,9 @@ actionDescriptor.params = { key: 'value' }; /////////////////////////////////////// // IResourceClass /////////////////////////////////////// -var resourceClass: ng.resource.IResourceClass; -var resource: ng.resource.IResource; -var resourceArray: ng.resource.IResource[]; +var resourceClass: IMyResourceClass; +var resource: IMyResource; +var resourceArray: IMyResource[]; resource = resourceClass.delete(); resource = resourceClass.delete({ key: 'value' }); @@ -63,12 +66,19 @@ resource = resourceClass.save({ key: 'value' }, { key: 'value' }); resource = resourceClass.save({ key: 'value' }, { key: 'value' }, function () { }); resource = resourceClass.save({ key: 'value' }, { key: 'value' }, function () { }, function () { }); +/////////////////////////////////////// +// IResourceService +/////////////////////////////////////// +var resourceService: ng.resource.IResourceService; +resourceClass = resourceService('test'); +resourceClass = resourceService('test'); +resourceClass = resourceService('test'); /////////////////////////////////////// // IModule /////////////////////////////////////// var mod: ng.IModule; -var resourceServiceFactoryFunction: ng.resource.IResourceServiceFactoryFunction; +var resourceServiceFactoryFunction: ng.resource.IResourceServiceFactoryFunction; var resourceService: ng.resource.IResourceService; resourceServiceFactoryFunction = function (resourceService) { return resourceClass }; From a859e22699e843e6934b4bbb934510c9c6916983 Mon Sep 17 00:00:00 2001 From: John Emau Date: Mon, 16 Dec 2013 19:15:42 -0800 Subject: [PATCH 4/5] added missing test for resource service factory and updated readme --- angularjs/README.md | 228 ++++++++++++++-------------- angularjs/angular-resource-tests.ts | 4 +- 2 files changed, 118 insertions(+), 114 deletions(-) diff --git a/angularjs/README.md b/angularjs/README.md index 9cf668559..363aea49d 100644 --- a/angularjs/README.md +++ b/angularjs/README.md @@ -72,7 +72,7 @@ TypeScript allows for static checking. Among other obvious things, that means yo Consider the following ordinary code: - function Controller($scope) { + function Controller($scope) { $scope.$broadcast('myEvent'); $scope.title = 'Yabadabadu'; } @@ -93,7 +93,7 @@ Since you are augmenting the $scope object, you should let the compiler know wha interface ICustomScope extends ng.IScope { title: string; } - + function Controller($scope: ng.ICustomScope) { $scope.$broadcast('myEvent'); $scope.title = 'Yabadabadu'; @@ -102,125 +102,127 @@ Since you are augmenting the $scope object, you should let the compiler know wha ## Examples ### Working with $resource +```ts +/// +/// - /// - /// +// We have the option to define arguments for a custom resource +interface IArticleParameters { + id: number; +} - // We have the option to define arguments for a custom resource - interface IArticleParameters { - id: number; +interface IArticleResource extends ng.resource.IResource { + title: string; + text: string; + date: Date; + author: number; + + // Although all actions defined on IArticleResourceClass are avaiable with + // the '$' prefix, we have the choice to expose only what we will use + $publish(): IArticleResource; + $unpublish(): IArticleResource; +} + +// Let's define a custom resource +interface IArticleResourceClass extends ng.resource.IResourceClass { + // Overload get to accept our custom parameters + get(): ng.resource.IResource; + get(params: IArticleParameters, onSuccess: Function): IArticleResource; + + // Add our custom resource actions + publish(): IArticleResource; + publish(params: IArticleParameters): IArticleResource; + unpublish(params: IArticleParameters): IArticleResource; +} + +function MainController($resource: ng.resource.IResourceService) { + + // IntelliSense will provide IActionDescriptor interface and will validate + // your assignment against it + var publishDescriptor: ng.resource.IActionDescriptor; + publishDescriptor = { + method: 'GET', + isArray: false + }; + + // I could still create a descriptor without the interface... + var unpublishDescriptor = { + method: 'POST' } - // Let's define a custom resource - interface IArticleResourceClass extends ng.resource.IResourceClass { - // Overload get to accept our custom parameters - get(): ng.resource.IResource; - get(params: IArticleParameters, onSuccess: Function): IArticleResource; + // A call to the $resource service returns a IResourceClass. Since + // our own IArticleResourceClass defines 2 more actions, we cast the return + // value to make the compiler aware of that + var articleResource = $resource('/articles/:id', null, { + publish : publishDescriptor, + unpublish : unpublishDescriptor + }); - // Add our custom resource actions - publish(): IArticleResource; - publish(params: IArticleParameters): IArticleResource; - unpublish(params: IArticleParameters): IArticleResource; - } - - interface IArticleResource extends ng.resource.IResource { - title: string; - text: string; - date: Date; - author: number; - - // Although all actions defined on IArticleResourceClass are avaiable with - // the '$' prefix, we have the choice to expose only what we will use - $publish(): IArticleResource; - $unpublish(): IArticleResource; - } - - function MainController($resource: ng.resource.IResourceService) { - - // IntelliSense will provide IActionDescriptor interface and will validate - // your assignment against it - var publishDescriptor: ng.resource.IActionDescriptor; - publishDescriptor = { - method: 'GET', - isArray: false - }; - - // I could still create a descriptor without the interface... - var unpublishDescriptor = { - method: 'POST' - } - - // A call to the $resource service returns a IResourceClass. Since - // our own IArticleResourceClass defines 2 more actions, we cast the return - // value to make the compiler aware of that - var articleResource = $resource('/articles/:id', null, { - publish : publishDescriptor, - unpublish : unpublishDescriptor - }); - - // Now we can do this - articleResource.unpublish({ id: 1 }); - - // IResourceClass.get() will be automatically available here - var article: IArticleResource = articleResource.get({id: 1}, function success() { - // Again, default + custom action here... - article.title = 'New Title'; - article.$save(); - article.$publish(); - }); - } - -### Working with $resource in angular-1.0 definitions - - /// - /// - - // Let's define a custom resource - interface IArticleResourceClass extends ng.resource.IResourceClass { - publish: ng.resource.IActionCall; - unpublish: ng.resource.IActionCall; - } - interface IArticleResource extends ng.resource.IResource { - title: string; - text: string; - date: Date; - author: number; - $publish: ng.resource.IActionCall; - $unpublish: ng.resource.IActionCall; - } - - function MainController($resource: ng.resource.IResourceService) { - - // IntelliSense will provide IActionDescriptor interface and will validate - // your assignment against it - var publishDescriptor: ng.resource.IActionDescriptor; - publishDescriptor = { - method: 'GET', - isArray: false - }; - - // I could still create a descriptor without the interface... - var unpublishDescriptor = { - method: 'POST' - } - - // A call to the $resource service returns a IResourceClass. Since - // our own IArticleResourceClass defines 2 more actions, we cast the return - // value to make the compiler aware of that - var articles = $resource('/articles/:id', null, { - publish : publishDescriptor, - unpublish : unpublishDescriptor - }); - - // Now we can do this - articles.unpublish({ id: 1 }); - - // IResourceClass.get() will be automatically available here - var article = articles.get({id: 1}); + // Now we can do this + articleResource.unpublish({ id: 1 }); + // IResourceClass.get() will be automatically available here + var article: IArticleResource = articleResource.get({id: 1}, function success() { // Again, default + custom action here... article.title = 'New Title'; article.$save(); article.$publish(); - + }); +} +``` + +### Working with $resource in angular-1.0 definitions +```ts +/// +/// + +// Let's define a custom resource +interface IArticleResourceClass extends ng.resource.IResourceClass { + publish: ng.resource.IActionCall; + unpublish: ng.resource.IActionCall; +} +interface IArticleResource extends ng.resource.IResource { + title: string; + text: string; + date: Date; + author: number; + $publish: ng.resource.IActionCall; + $unpublish: ng.resource.IActionCall; +} + +function MainController($resource: ng.resource.IResourceService) { + + // IntelliSense will provide IActionDescriptor interface and will validate + // your assignment against it + var publishDescriptor: ng.resource.IActionDescriptor; + publishDescriptor = { + method: 'GET', + isArray: false + }; + + // I could still create a descriptor without the interface... + var unpublishDescriptor = { + method: 'POST' } + + // A call to the $resource service returns a IResourceClass. Since + // our own IArticleResourceClass defines 2 more actions, we cast the return + // value to make the compiler aware of that + var articles = $resource('/articles/:id', null, { + publish : publishDescriptor, + unpublish : unpublishDescriptor + }); + + // Now we can do this + articles.unpublish({ id: 1 }); + + // IResourceClass.get() will be automatically available here + var article = articles.get({id: 1}); + + // Again, default + custom action here... + article.title = 'New Title'; + article.$save(); + article.$publish(); + +} +``` diff --git a/angularjs/angular-resource-tests.ts b/angularjs/angular-resource-tests.ts index 911267f15..b223b8171 100644 --- a/angularjs/angular-resource-tests.ts +++ b/angularjs/angular-resource-tests.ts @@ -78,8 +78,10 @@ resourceClass = resourceService('test'); // IModule /////////////////////////////////////// var mod: ng.IModule; -var resourceServiceFactoryFunction: ng.resource.IResourceServiceFactoryFunction; +var resourceServiceFactoryFunction: ng.resource.IResourceServiceFactoryFunction; var resourceService: ng.resource.IResourceService; +resourceClass = resourceServiceFactoryFunction(resourceService); + resourceServiceFactoryFunction = function (resourceService) { return resourceClass }; mod = mod.factory('factory name', resourceServiceFactoryFunction); From 459e286cd0fc287a3373265816cf00f0a08417ee Mon Sep 17 00:00:00 2001 From: John Emau Date: Mon, 16 Dec 2013 19:17:47 -0800 Subject: [PATCH 5/5] added syntax highlighting --- angularjs/README.md | 50 +++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/angularjs/README.md b/angularjs/README.md index 363aea49d..263e046ea 100644 --- a/angularjs/README.md +++ b/angularjs/README.md @@ -43,11 +43,11 @@ To avoid cluttering the list of suggestions as you type in your IDE, all interfa **ngMockE2E** does not define a new namespace, but rather modifies some of **ng**'s interfaces. Bellow is an example of how to use the interfaces: - - function MainController($scope: ng.IScope, $http: ng.IHttpService) { - // code assistance will now be available for $scope and $http - } - +```ts +function MainController($scope: ng.IScope, $http: ng.IHttpService) { + // code assistance will now be available for $scope and $http +} +``` ## Services and other injectables @@ -71,33 +71,35 @@ The **$httpProvider**, thus, is defined by **ng.IHttpProvider**. TypeScript allows for static checking. Among other obvious things, that means you're gonna have to extend interfaces when you need to augment an object whose interface has been defined, because otherwise the compiler will see it as an error to try to assign a value to a unspecified member. Consider the following ordinary code: - - function Controller($scope) { - $scope.$broadcast('myEvent'); - $scope.title = 'Yabadabadu'; - } - +```ts +function Controller($scope) { + $scope.$broadcast('myEvent'); + $scope.title = 'Yabadabadu'; +} +``` That will not produce any compilation error because the compiler does not know the first thing about $scope to do any checking. For that same reason, you will not get any assistance either. Now consider this: - - function Controller($scope: ng.IScope) { - $scope.$broadcast('myEvent'); - $scope.title = 'Yabadabadu'; - } +```ts +function Controller($scope: ng.IScope) { + $scope.$broadcast('myEvent'); + $scope.title = 'Yabadabadu'; +} +``` Now we annotated `$scope` with the interface `ng.IScope`. The compiler now knows that, among other members, `$scope` has a method called `$broadcast`. That interface, however, does not define a `title` property. The compiler will complain about it. Since you are augmenting the $scope object, you should let the compiler know what to expect then: +```ts +interface ICustomScope extends ng.IScope { + title: string; +} - interface ICustomScope extends ng.IScope { - title: string; - } - - function Controller($scope: ng.ICustomScope) { - $scope.$broadcast('myEvent'); - $scope.title = 'Yabadabadu'; - } +function Controller($scope: ng.ICustomScope) { + $scope.$broadcast('myEvent'); + $scope.title = 'Yabadabadu'; +} +``` ## Examples