简体   繁体   English

如何定义包含泛型类型变量的类型数组

[英]How to define an array of a type that includes a generic type variable

I have the following types in Typescript:我在 Typescript 中有以下类型:

type Task<T> = () => Promise<T>;
type QueueItem<T> = { task: Task<T>; resolve: (v: T) => void; reject: () => any };

I have a class that uses these types:我有一个使用这些类型的类:

class Queue {
  private queue: QueueItem<T>[] = [];
  insertTask<T>(task: () => Promise<T>): Promise<T> {
    const promise = new Promise((resolve, reject) => {
      this.queue.push({ task, resolve, reject });
    });
    return promise;
  }
}

Im trying to define a new type that is an array of QueueItem<T> .我正在尝试定义一个新类型,它是QueueItem<T>的数组。 I have tried:我试过了:

queue = [] as QueueItem<T>[];

queue: QueueItem<T>[] = [];

queue<T>: QueueItem<T>[] = [];

But none worked.但没有一个奏效。 I keep getting the following error:我不断收到以下错误:

Cannot find name 'T'.ts(2304)

How can I define it correctly?我怎样才能正确定义它?

You can try it in this demo您可以在此演示中尝试

You can't have a variable that is typed with an open type parameter.您不能拥有使用开放类型参数键入的变量。 You can use unknown (if T is covariant), never (if T is contravariant) or any (works for T invariant or any other varinance but is less safe)您可以使用unknown (如果T是协变的)、 never (如果T是逆变的)或any (适用于T不变量或任何其他变量,但不太安全)

In your case T appears in both covariant (in task ) and in a contravariant position (in position in resolve ) so any is the only choice:在你的情况下, T出现在协变(在task )和逆变位置(在 position in resolve )中,所以any是唯一的选择:

type Task<T> = () => Promise<T>;
type QueueItem<T> = { task: Task<T>; resolve: (v:T) => void; reject: () => any };


class Queue {
  private queue: QueueItem<any>[] = [];

  insertTask<T>(task: () => Promise<T>): Promise<T> {
    const promise = new Promise<T>((resolve, reject) => {
      this.queue.push({ task, resolve, reject });
    });
    return promise;
  }
}```
[Playground Link](https://www.typescriptlang.org/play/?ssl=14&ssc=2&pln=1&pc=1#code/C4TwDgpgBAKghgZwNYB4YD4oF4oAoCU2mACgE4D2AtgJYIRroDcAUKJFAIoCuEPAksAiUG2KAG8owREgBcsaQ0ZRSEBOQA2ANwhzcmmTEJZMm8tQAmSlQCsIAY2C6jmOADsQUAL4tmzO+sQETh4ecWYoKDBSak04QSgARxCdYN4IASEUNxB0AG0AXVEClgjwqGpXOlJgeGQGXClkJyIoMipaegx8OTaaOhExMoi7ckrgSIo+6BxXCAB3VsmO+twVNS0IABplCFsHZzCIo8kAC1oAOiS087AuBBPcCUakbbWNbVfd+3HPfBKj37-CIqYBcUiuCbtOj-TzMTxAA)

Since you are inserting many different `T` in `queue` there is no way to preserve the types off all of these. If you were to give all the tasks to ever be executed in the `Queue` constructor you could use a tuple type, but that seems to be antithetical to the point of the `Queue`.


Another option is to make `Queue` generic if you just need to forward the type parameter:


```ts
type Task<T> = () => Promise<T>;
type QueueItem<T> = { task: Task<T> };

class Queue<T> {
  private queue: QueueItem<T>[] = [
  ];
}

Playground Link 游乐场链接

The Query class is missing the T generic, so typescript do know of which type the queue items are. Query类缺少T泛型,因此打字稿确实知道队列项是哪种类型。

class Queue<T> {
  private queue: QueueItem<T>[] = [];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM