Typescript:Spread类型只能从对象类型创建

Mor*_*sen 32 typescript

function foo<T extends object>(t: T): T {

  return {
    ...t    // Error: [ts] Spread types may only be created from object types.
  }
}
Run Code Online (Sandbox Code Playgroud)

我知道github上存在问题,但我无法弄清楚什么是固定的,什么不是,他们有2695个未解决的问题.所以我在这里发帖 我正在使用最新的Typescript 2.9.2.

如果上面的代码不起作用?如果可能,我该如何解决?

jma*_*eis 55

这在TypeScript版本3.2中得到修复.请参阅发行说明.


看起来不支持使用泛型类型的传播,但是有一个关于它的GitHub问题:Microsoft/TypeScript#10727.

现在您可以使用类型断言@Jevgeni 评论:

function foo<T extends object>(t: T): T {
  return { ...(t as object) } as T;
}
Run Code Online (Sandbox Code Playgroud)

或者你可以使用Object.assign哪个有正确的类型定义.

function foo<T extends object>(t: T): T {
  return Object.assign({}, t);
}
Run Code Online (Sandbox Code Playgroud)

  • Typescript 4.2 仍然面临同样的问题。我按照 linter @@ 的建议投射 `...(t as Record&lt;string,unknown&gt;)` 来传递 lint (8认同)
  • 我正在使用版本“3.7.3”并且仍然发生 (7认同)
  • 你知道吗,正如`tslint`所说:`[tslint]改为使用对象扩展运算符.:'( (4认同)
  • @CliteTailor 因此,如果您不喜欢,请更改 lint 规则。Linter 应该帮助你建立某些规则,而不是阻止你写你想写的东西。 (3认同)

Muh*_*ouk 28

您可以使用空白大括号 {} 或如下示例所示的接口:

goodsArray.map(good => {
  return {
    id: good.payload.doc.id,
    ...good.payload.doc.data() as {}
  };
});
Run Code Online (Sandbox Code Playgroud)

或者

goodsArray.map(good => {
  return {
    id: good.payload.doc.id,
    ...good.payload.doc.data() as Goods // 'Goods' is my interface name
  };
});
Run Code Online (Sandbox Code Playgroud)


Tit*_*mir 9

Typecript 3.2版解决了这个问题.改善传播和休息参数处理的两个PR是:

您现在可以尝试使用它npm install typescript@3.2.

使用3.2,您的代码将按原样运行.

版本3.2已于2018年11月29日发布,您可以在此处阅读更多相关信息.


Sim*_*ver 6

如果在版本 3.2 后您仍然收到此错误,那么您可能有“上游”类型错误,导致对象而unknown不是实际对象。例如,如果您有扩展表达式{ ...getData() },但您的getData函数有编译错误,您可能会看到此错误。

因此,请检查浏览器控制台中是否有任何编译器错误,因为最终的错误可能会产生误导。