Skip to content

Instantly share code, notes, and snippets.

@Hotell
Last active August 29, 2015 14:06
Show Gist options
  • Save Hotell/e77b5fe543b3b473e851 to your computer and use it in GitHub Desktop.
Save Hotell/e77b5fe543b3b473e851 to your computer and use it in GitHub Desktop.
Webstorm type infer bug
declare module ng{
interface IAngularStatic{
}
interface IPromise<T> {
then<TResult>(successCallback: (promiseValue: T) => IPromise<TResult>, errorCallback?: (reason: any) => any, notifyCallback?: (state: any) => any): IPromise<TResult>;
then<TResult>(successCallback: (promiseValue: T) => TResult, errorCallback?: (reason: any) => TResult, notifyCallback?: (state: any) => any): IPromise<TResult>;
}
}
declare module ng.resource{
// Just a reference to facilitate describing new actions
interface IActionDescriptor {
method: string;
isArray?: boolean;
params?: any;
headers?: any;
}
interface IResourceArray<T> extends Array<T> {
/** the promise of the original server interaction that created this collection. **/
$promise : ng.IPromise<IResourceArray<T>>;
$resolved : boolean;
}
interface IResourceService {
<T, U>(url: string, paramDefaults?: any,
/** example: {update: { method: 'PUT' }, delete: deleteDescriptor }
where deleteDescriptor : IActionDescriptor */
actionDescriptors?: any): U;
}
interface IResourceClass<T> {
new(dataOrParams? : any) : T;
get(): T;
get(params: Object): T;
get(success: Function, error?: Function): T;
get(params: Object, success: Function, error?: Function): T;
get(params: Object, data: Object, success?: Function, error?: Function): T;
query(): IResourceArray<T>;
save(): T;
remove(): T;
delete(): T;
}
interface IResource<T> {
$get(): ng.IPromise<T>;
$get(params?: Object, success?: Function, error?: Function): ng.IPromise<T>;
$get(success: Function, error?: Function): ng.IPromise<T>;
$query(): ng.IPromise<IResourceArray<T>>;
$save(): ng.IPromise<T>;
$remove(): ng.IPromise<T>;
$delete(): ng.IPromise<T>;
/** the promise of the original server interaction that created this instance. **/
$promise : ng.IPromise<T>;
$resolved : boolean;
}
}
declare var angular: ng.IAngularStatic;
// ----------------------------------------------------------------------------
// CUSTOM RESOURCE TS TYPINGS
// ----------------------------------------------------------------------------
// We have the option to define arguments for a custom resource
interface IArticleParameters {
id: number;
}
interface IArticleResource extends ng.resource.IResource<IArticleResource> {
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(): ng.IPromise<IArticleResource>;
$unpublish(): ng.IPromise<IArticleResource>;
}
// Let's define a custom resource
interface IArticleResourceClass extends ng.resource.IResourceClass<IArticleResource> {
// Overload get to accept our custom parameters
get(): IArticleResource;
get(params: IArticleParameters): 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'
};
// 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: IArticleResourceClass = $resource<IArticleResource, IArticleResourceClass>('/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});
article.$promise.then(function success() {
// Again, default + custom action here...
article.title = "My title";
article.$save();
article.$publish();
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment