打字稿:传播类型只能从对象类型创建

Posted

技术标签:

【中文标题】打字稿:传播类型只能从对象类型创建【英文标题】:Typescript: Spread types may only be created from object types 【发布时间】:2018-12-13 19:44:47 【问题描述】:
function foo<T extends object>(t: T): T 

  return 
    ...t // Error: [ts] Spread types may only be created from object types.
  

我知道 github 上存在问题,但我无法弄清楚哪些已修复,哪些未修复,他们有 2695 个未解决的问题。所以我在这里发帖。我正在使用最新的 Typescript 2.9.2。

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

【问题讨论】:

看起来它无法正确地将t 转换为object。试试function foo&lt;T extends object&gt;(t: T): T return ...(t as object) as T; ,这很奇怪,但有效 【参考方案1】:

这已在 TypeScript 版本 3.2 中得到修复。见Release Notes。


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

现在你可以使用type assertion 像@Jevgeni commented:

function foo<T extends object>(t: T): T 
  return  ...(t as object)  as T;

或者您可以使用具有正确类型定义的Object.assign

function foo<T extends object>(t: T): T 
  return Object.assign(, t);

【讨论】:

优秀。我现在将使用 Object.assign。谢谢! 你知道吗,正如tslint 所说:[tslint] Use the object spread operator instead. :'( @CliteTailor 如果您不喜欢,请更改 lint 规则。 Linter 应该帮助你建立某些规则,而不是阻止你写你想写的东西。 我正在使用版本 3.7.3 并且仍在使用 Typescript 4.2 仍然面临同样的问题。我投 ...(t as Record&lt;string, unknown&gt;) 按照 linter @@ 的建议通过 lint【参考方案2】:

Typescript 3.2 版修复了这个问题。改进对扩展和剩余参数的处理的两个 PR 是:

Generic object rest variables and parameters Generic spread expressions in object literals

您现在可以使用npm install typescript@3.2 试用。

在 3.2 中,您的代码可以按原样运行。

3.2 版本已于 2018 年 11 月 29 日发布,您可以阅读更多信息here。

【讨论】:

11月最后一天发布:blogs.msdn.microsoft.com/typescript/2018/11/29/… 我在 4.5 版中仍然遇到这个错误,所以这可能没有修复 @Danielo515 你的确切代码是什么?也许情况有点不同?我很想看看 @TitianCernicova-Dragomir,如果有兴趣,我有类似的问题,例如:let someObject: [key: string]: number ; can't spread ...someObject【参考方案3】:

您可以使用空白大括号 或类似以下示例的界面:

goodsArray.map(good => 
  return 
    id: good.payload.doc.id,
    ...good.payload.doc.data() as 
  ;
);

goodsArray.map(good => 
  return 
    id: good.payload.doc.id,
    ...good.payload.doc.data() as Goods // 'Goods' is my interface name
  ;
);

【讨论】:

更干净的方式吗?【参考方案4】:

此答案可能有助于在使用 angular 和 firestoe 时解决相同的问题。

return id: item.payload.doc.id, ...item.payload.doc.data() as Employee

这会引发同样的错误。要修复,您必须像这样进行更改。

return id: item.payload.doc.id, ...item.payload.doc.data() as Employee

【讨论】:

【参考方案5】:

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

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

【讨论】:

以上是关于打字稿:传播类型只能从对象类型创建的主要内容,如果未能解决你的问题,请参考以下文章

打字稿 |从对象 T 中提取具有类型 K 值的所有键名

打字稿:如何根据对象键/值类型在 ES6 映射中创建条目

打字稿:使用对象值作为新类型的键

从打字稿中的对象获取特定类型的所有键[重复]

打字稿:如何将对象映射到类型?

传播类型只能从对象类型创建