Skip to content

Instantly share code, notes, and snippets.

@chriskrycho
Created December 11, 2017 18:23
Show Gist options
  • Select an option

  • Save chriskrycho/9ed39076ccb698023e57e59080fedecd to your computer and use it in GitHub Desktop.

Select an option

Save chriskrycho/9ed39076ccb698023e57e59080fedecd to your computer and use it in GitHub Desktop.
Ember Concurrency basic type defs
import ComputedProperty from '@ember/object/computed';
import RSVP from 'rsvp';
export enum TaskInstanceState {
Dropped = 'dropped',
Canceled = 'canceled',
Finished = 'finished',
Running = 'running',
Waiting = 'waiting',
}
export interface TaskProperty<T> extends ComputedProperty<T> {
cancelOn(eventNames: string[]): this;
debug(): this;
drop(): this;
enqueue(): this;
group(groupPath: string): this;
keepLatest(): this;
maxConcurrency(n: number): this;
on(eventNames: string[]): this;
restartable(): this;
}
export interface TaskInstance<T> extends PromiseLike<T> {
readonly error?: any;
readonly hasStarted: ComputedProperty<boolean>;
readonly isCanceled: ComputedProperty<boolean>;
readonly isDropped: ComputedProperty<boolean>;
readonly isError: boolean;
readonly isFinished: ComputedProperty<boolean>;
readonly isRunning: ComputedProperty<boolean>;
readonly isSuccessful: boolean;
readonly state: ComputedProperty<TaskInstanceState>;
readonly value?: T;
cancel(): void;
catch(): RSVP.Promise<any>;
finally(): RSVP.Promise<any>;
then<TResult1 = T, TResult2 = never>(
onfulfilled?: ((value: T) => TResult1 | RSVP.Promise<TResult1>) | undefined | null,
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null
): RSVP.Promise<TResult1 | TResult2>;
}
export enum TaskState {
Running = 'running',
Queued = 'queued',
Idle = 'idle',
}
interface Task<T, P> extends TaskProperty<T> {
readonly isIdle: boolean;
readonly isQueued: boolean;
readonly isRunning: boolean;
readonly last?: TaskInstance<T>;
readonly lastCanceled?: TaskInstance<T>;
readonly lastComplete?: TaskInstance<T>;
readonly lastErrored?: TaskInstance<T>;
readonly lastIncomplete?: TaskInstance<T>;
readonly lastPerformed?: TaskInstance<T>;
readonly lastRunning?: TaskInstance<T>;
readonly lastSuccessful?: TaskInstance<T>;
readonly performCount: number;
readonly state: TaskState;
cancelAll(): void;
perform: P;
}
export declare function timeout(ms: number): RSVP.Promise<void>;
export declare function task<T, A>(generatorFn: () => Iterator<T>): Task<T, () => TaskInstance<T>>;
export declare function task<T, A>(
generatorFn: (a: A) => Iterator<T>
): Task<T, (a: A) => TaskInstance<T>>;
export declare function task<T, A>(
generatorFn: (a: A) => Iterator<PromiseLike<T>>
): Task<T, (a: A) => TaskInstance<T>>;
export declare function task<T, A1, A2>(
generatorFn: (a1: A1, a2: A2) => Iterator<T>
): Task<T, (a1: A1, a2: A2) => TaskInstance<T>>;
export declare function task<T, A1, A2>(
generatorFn: (a1: A1, a2: A2) => Iterator<PromiseLike<T>>
): Task<T, (a1: A1, a2: A2) => TaskInstance<T>>;
export declare function task<T, A1, A2, A3>(
generatorFn: (a1: A1, a2: A2, a3: A3) => Iterator<T>
): Task<T, (a1: A1, a2: A2, a3: A3) => TaskInstance<T>>;
export declare function task<T, A1, A2, A3>(
generatorFn: (a1: A1, a2: A2, a3: A3) => Iterator<PromiseLike<T>>
): Task<T, (a1: A1, a2: A2, a3: A3) => TaskInstance<T>>;
export declare function task<T, A1, A2, A3, A4>(
generatorFn: (a1: A1, a2: A2, a3: A3, a4: A4) => Iterator<T>
): Task<T, (a1: A1, a2: A2, a3: A3, a4: A4) => TaskInstance<T>>;
export declare function task<T, A1, A2, A3, A4>(
generatorFn: (a1: A1, a2: A2, a3: A3, a4: A4) => Iterator<PromiseLike<T>>
): Task<T, (a1: A1, a2: A2, a3: A3, a4: A4) => TaskInstance<T>>;
export declare function task<T, A1, A2, A3, A4, A5>(
generatorFn: (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) => Iterator<T>
): Task<T, (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) => TaskInstance<T>>;
export declare function task<T, A1, A2, A3, A4, A5>(
generatorFn: (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) => Iterator<PromiseLike<T>>
): Task<T, (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) => TaskInstance<T>>;
export declare function task<T, A1, A2, A3, A4, A5, A6>(
generatorFn: (a1: A1, a2: A2, a3: A3, a4: A4, a6: A6) => Iterator<T>
): Task<T, (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6) => TaskInstance<T>>;
export declare function task<T, A1, A2, A3, A4, A5, A6>(
generatorFn: (a1: A1, a2: A2, a3: A3, a4: A4, a6: A6) => Iterator<PromiseLike<T>>
): Task<T, (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6) => TaskInstance<T>>;
@lolmaus
Copy link

lolmaus commented Dec 25, 2018

Thx!

Can you please provide usage samples?

E. g. how do you type this:

class Foo extends Component {
  @restartableTask
  *myTask() {
    return yield this.store.findAll('bar');
  }

  @action
  fetch() {
    this.myTask.perform();
  }
}

There are two issues here:

  1. myTask is considered to be a generator function and .perform is not supposed to exist on it.
  2. A decorator is not supposed to change the type of whatever passed into it. Here we have a generator function being substituted by a Task object.

How do I resolve these typing issues?

@Alonski
Copy link

Alonski commented Sep 3, 2019

Thanks!
I ended up doing this:

declare module "ember-concurrency" {
    import ComputedProperty from "@ember/object/computed";
    import RSVP from "rsvp";

    enum TaskInstanceState {
        Dropped = "dropped",
        Canceled = "canceled",
        Finished = "finished",
        Running = "running",
        Waiting = "waiting"
    }

    interface TaskProperty<T> extends ComputedProperty<T> {
        cancelOn(eventNames: string[]): this;
        debug(): this;
        drop(): this;
        enqueue(): this;
        group(groupPath: string): this;
        keepLatest(): this;
        maxConcurrency(n: number): this;
        on(eventNames: string[]): this;
        restartable(): this;
    }

    interface TaskInstance<T> extends PromiseLike<T> {
        readonly error?: any;
        readonly hasStarted: ComputedProperty<boolean>;
        readonly isCanceled: ComputedProperty<boolean>;
        readonly isDropped: ComputedProperty<boolean>;
        readonly isError: boolean;
        readonly isFinished: ComputedProperty<boolean>;
        readonly isRunning: ComputedProperty<boolean>;
        readonly isSuccessful: boolean;
        readonly state: ComputedProperty<TaskInstanceState>;
        readonly value?: T;
        cancel(): void;
        catch(): RSVP.Promise<any>;
        finally(): RSVP.Promise<any>;
        then<TResult1 = T, TResult2 = never>(
            onfulfilled?: ((value: T) => TResult1 | RSVP.Promise<TResult1>) | undefined | null,
            onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null
        ): RSVP.Promise<TResult1 | TResult2>;
    }

    enum TaskState {
        Running = "running",
        Queued = "queued",
        Idle = "idle"
    }

    interface Task<T, P> extends TaskProperty<T> {
        perform: P;
        readonly isIdle: boolean;
        readonly isQueued: boolean;
        readonly isRunning: boolean;
        readonly last?: TaskInstance<T>;
        readonly lastCanceled?: TaskInstance<T>;
        readonly lastComplete?: TaskInstance<T>;
        readonly lastErrored?: TaskInstance<T>;
        readonly lastIncomplete?: TaskInstance<T>;
        readonly lastPerformed?: TaskInstance<T>;
        readonly lastRunning?: TaskInstance<T>;
        readonly lastSuccessful?: TaskInstance<T>;
        readonly performCount: number;
        readonly state: TaskState;
        cancelAll(): void;
    }

    function timeout(ms: number): RSVP.Promise<void>;

    function task<T, A>(generatorFn: () => Iterator<T>): Task<T, () => TaskInstance<T>>;

    function task<T, A>(generatorFn: (a: A) => Iterator<T>): Task<T, (a: A) => TaskInstance<T>>;

    function task<T, A>(generatorFn: (a: A) => Iterator<PromiseLike<T>>): Task<T, (a: A) => TaskInstance<T>>;

    function task<T, A1, A2>(
        generatorFn: (a1: A1, a2: A2) => Iterator<T>
    ): Task<T, (a1: A1, a2: A2) => TaskInstance<T>>;

    function task<T, A1, A2>(
        generatorFn: (a1: A1, a2: A2) => Iterator<PromiseLike<T>>
    ): Task<T, (a1: A1, a2: A2) => TaskInstance<T>>;

    function task<T, A1, A2, A3>(
        generatorFn: (a1: A1, a2: A2, a3: A3) => Iterator<T>
    ): Task<T, (a1: A1, a2: A2, a3: A3) => TaskInstance<T>>;

    function task<T, A1, A2, A3>(
        generatorFn: (a1: A1, a2: A2, a3: A3) => Iterator<PromiseLike<T>>
    ): Task<T, (a1: A1, a2: A2, a3: A3) => TaskInstance<T>>;

    function task<T, A1, A2, A3, A4>(
        generatorFn: (a1: A1, a2: A2, a3: A3, a4: A4) => Iterator<T>
    ): Task<T, (a1: A1, a2: A2, a3: A3, a4: A4) => TaskInstance<T>>;

    function task<T, A1, A2, A3, A4>(
        generatorFn: (a1: A1, a2: A2, a3: A3, a4: A4) => Iterator<PromiseLike<T>>
    ): Task<T, (a1: A1, a2: A2, a3: A3, a4: A4) => TaskInstance<T>>;

    function task<T, A1, A2, A3, A4, A5>(
        generatorFn: (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) => Iterator<T>
    ): Task<T, (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) => TaskInstance<T>>;

    function task<T, A1, A2, A3, A4, A5>(
        generatorFn: (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) => Iterator<PromiseLike<T>>
    ): Task<T, (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) => TaskInstance<T>>;

    function task<T, A1, A2, A3, A4, A5, A6>(
        generatorFn: (a1: A1, a2: A2, a3: A3, a4: A4, a6: A6) => Iterator<T>
    ): Task<T, (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6) => TaskInstance<T>>;

    function task<T, A1, A2, A3, A4, A5, A6>(
        generatorFn: (a1: A1, a2: A2, a3: A3, a4: A4, a6: A6) => Iterator<PromiseLike<T>>
    ): Task<T, (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6) => TaskInstance<T>>;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment