Generic type in Promise

promise typescript
typescript promise type
promise<void typescript
generic types
convert promise type to type
typescript promise return type
typescript pass type as parameter
typescript wait for promise to resolve

I designed a class Task to compute some value T synchronously. Now I want provide a way to retrieve the value asynchronously.

This is the first time I use Promise in Scala. I wrote the following code:

abstract class Task[+T](
...

    final def result: Try[T] = {
        if (state != TaskState.Terminated)
            throw new IllegalStateException("Task must be terminated")
        cached_result
    }
}



// OTHER CLASS
    private val executedTasks = HashMap[TaskID, Task[_]]() 
    private val promises = HashMap[TaskID, Promise[Any]]()

    ...

    def onTaskEvent(taskEvent: TaskEvent): Unit = {
        ...
        val task: Task[_] = ...
        promises.get( task.id ).foreach( p => p complete task.result ) // fulfill the promise with a Try[_]
        ...
    }

    ...

    /**
    * if the task exists and is terminated I return the result immediately
    * otherwise I make a promise
    */
    def getTaskResult(uuid: TaskID): Future[_] = {
        executedTasks.get(uuid) match {
            case Some(task) if task.state == TaskState.Terminated => Future.fromTry(task.result)
            case _ => {
                val p = Promise[Any]()
                promises.put(uuid, p)
                p.future
            }
        }
    }

This code works but I want to get rid of that ugly Any in Promise and continue to use generic types. When I tried to use Promise[_] I get mysterious compiler error of the kind "expected: Try[_] actual: Try[_$1]" or "Promise[_]: unbound wildcard type".

Thanks for your help.

The problem is that there's no relationship between the type parameters of Task and Promise for the same key if you use Promise[_]; you could have e.g. a Task[Int] and a Promise[String], in which case p complete task.result makes no sense. But honestly, I'd argue that in this case what you have is pretty much the best you can do (without changing the design significantly) for two reasons:

  1. Future is covariant, so Future[_] is basically equivalent to Future[Any].

  2. if the task exists and is terminated I return the result immediately otherwise I make a promise

    If the task doesn't exist, do you have a way to know what its type parameter is going to be?

Exploring TypeScript generics - Ben Brostoff, In TypeScript, promises can be initialized such that they “lock” a generic into a type: The Promise source makes the warning above possible. IDEs  Generic type 'Promise<T, R>' requires 2 type argument in Telerik AppBuilder developer tools AppBuilder in-browser client - Telerik Forums.

I eventually found a satisfying design for my need, while enforcing typing. Basically, the idea is that the caller of getTaskResult knows which type he expects for a given task. So it's not abnormal to cast the elements of the generic collection to the expected type when you retrieve them. I solved also the problem of multiple promises for the same task with a multimap.

    protected val promises = new HashMap[TaskID, collection.mutable.Set[Promise[_]]] with collection.mutable.MultiMap[TaskID, Promise[_]]

    ...

    protected def makePromise[T](task: Task[T]): Promise[T] = {
        val p = Promise[T]()
        promises.addBinding(task.id, p)
        p
    }

    protected def fulfillPromise[T](task: Task[T]): Unit =
        promises.remove(task.id).foreach(p => p.map(_.asInstanceOf[Promise[T]]).foreach(_ complete task.result))


    protected def futureResult[T](task: Task[T]): Future[T] = {
        if (task.state == TaskState.Terminated)
            Future.fromTry(task.result)
        else
            makePromise(task).future
    }


    def getTaskResult[T](uuid: TaskID): Future[T] =
        taskTracker.getTaskById(uuid).map(_.asInstanceOf[Task[T]]).fold(throw new Exception("Unknown task"))(futureResult(_))

Promise<T> should be Promise<T1,T2> · Issue #22162 · microsoft , Promise { if(bar){ return Promise.resolve(true); // boolean type } /48954365/​use-generics-to-specify-type-of-return-value/48958224  A Generic Promise implementation for TypeScript Installing Promise.ts. Using Promise.ts. The pattern for creating promises is as follows: First a "deferred" is created that represent a Ideas. An explicit parallel combinator. Instead of any [], use Tuples for the return type of when (). Because

hum, I feel there is still a problem with this function:

protected def fulfillPromise[T](task: Task[T]): Unit =
        promises.remove(task.id).foreach(p => p.map(_.asInstanceOf[Promise[T]]).foreach(_ complete task.result))

It is not protected against ClassCastException in the scope of the notifier, I think there is a need to use TypeTag in Promise here.

Type when using Promises? : typescript, All examples I see that declare a function that returns a Promise declare it to be of return type Promise<T> , where T is the type of the value in the resolved case. Generic Types # In previous sections, we created generic identity functions that worked over a range of types. In this section, we’ll explore the type of the functions themselves and how to create generic interfaces. The type of generic functions is just like those of non-generic functions, with the type parameters listed first, similarly to

Generic Type, Here, we will use a type variable, a special kind of variable that works on types rather than values. function identity<T>(arg: T): T { return arg  If you use the same type of rejection reason as the promise will return, the types are all compatible and the compiler can’t help you. The most common case would be Promise getting mixed up with a rejection string.

Asynchronous Processing with TypeScript and Generic Promises , TypeScript providing support for generic Promises, you get both type safety and IntelliSense support. By Peter Vogel; 03/30/2015. While JavaScript itself is  const one = new Promise<string> ((resolve, reject) => {}); In this Promise, I have used the promise constructor to take in string as the generic type for the Promise’s resolve value. The promise constructor takes an executor callback which the compiler will call by the runtime with these two arguments:

Getting Type Safety for TypeScript Promises – Steve Fenton, function go(isWorking: boolean): Promise<string> { return new Promise((resolve, reject) => { window.setTimeout(() => { if (isWorking)  A Promise is an object representing the eventual completion or failure of an asynchronous operation. Since most people are consumers of already-created promises, this guide will explain consumption of returned promises before explaining how to create them.

Comments
  • See my solution below.
  • You could have the expected type on the TaskID as well: def getTaskResult[T](uuid: TaskID[T]): Future[T] = taskTracker.getTaskById(uuid).mapTo[Task[T]].fold(throw new Exception("Unknown task"))(futureResult(_))
  • TaskID is currently mapped to the UUID type
  • type TaskId[T] = UUID