typescript 类型Void[]数组无法指派给类型Void

xxls0lw8  于 2022-11-26  发布在  TypeScript
关注(0)|答案(3)|浏览(215)

我希望类型void[]与类型void兼容。特别是在使用Promise.all时。

class Foo {
  delete(): Promise<void> {
    // do delete
    return Promise.resolve();
  }
  deleteMany(list: Foo[]): Promise<void> {
    return Promise.all(list.map((x) => x.delete()));
  }

打字错误:
'类型'Promise〈void[]〉'无法分配给类型'Promise '类型'void[]'无法分配给类型' void ''
我知道有两种方法可以解决这个问题:
1.将deleteMany标记为返回Promise〈void[]〉。

  1. Promise.all的承诺链,返回已解决的承诺。例如
return Promise.all(list.map((x) => x.delete())).then(() => Promise.resolve());

第二个问题更糟,因为这段代码是在JavaScript中执行的,但第一个问题让开发人员感到困惑。是Typescript对Promise.all的支持很差,还是它被他们的文档忽略了?有人找到更好的解决方案吗?

5gfr0r5j

5gfr0r5j1#

1(将deleteMany标记为返回Promise<void[]>)至少对我来说是绝对可以的。
但是,如果确实要返回Promise<void>,则可以使用async/await

class Foo {
  delete(): Promise<void> {
    // do delete
    return Promise.resolve();
  }
  async deleteMany(list: Foo[]): Promise<void> {
    await Promise.all(list.map((x) => x.delete()));
  }

函数的行为方式完全相同。

t3psigkw

t3psigkw2#

void在设计上与除nullundefined之外的任何其他类型不兼容,因此它与void[]不兼容。
你可以使用Promise<{}>作为deleteMany的结果类型,也就是说,promise解析为空对象。它是有效的,因为空对象类型没有属性(所以它不能以任何方式有意义地使用),而且,因为它没有属性(再次),它几乎可以被赋值为任何东西,包括void[]

class Foo {
    delete(): Promise<void> {
        // do delete
        return Promise.resolve();
    }
    deleteMany(list: Foo[]): Promise<{}> {
        return Promise.all(list.map((x) => x.delete()));
    }
}
nnvyjq4y

nnvyjq4y3#

由于promise实际上并不包含数据,因此您可以安全地进行如下转换:

class Foo {
  delete(): Promise<void> {
    // do delete
    return Promise.resolve();
  }
  deleteMany(list: Foo[]): Promise<void> {
    return (Promise.all(list.map((x) => x.delete()))) as unknown as Promise<void>;
  }
}

中间unknown可以欺骗TS编译器允许强制转换

相关问题