为啥打字稿抱怨对象必须是扩展类型中的对象

Posted

技术标签:

【中文标题】为啥打字稿抱怨对象必须是扩展类型中的对象【英文标题】:Why does typescript complain that an object must be an object in spread types为什么打字稿抱怨对象必须是扩展类型中的对象 【发布时间】:2018-01-05 04:26:03 【问题描述】:

为什么 TSC 说“...base”必须是一个对象,我该如何解决这个问题,同时仍然保留“base”对象的类型。

function aFunction<T extends object>(base: T) 
  const anObject =  test:"value" 
  if (typeof base !== 'object')  return 

// the following line causes a TSC error, saying that spread types can only be
// created from object types and highlighting base as the problem...  wut?

  const merged =  ...base, anObject 
  return merged

例如,以下没有编译器错误但是丢失了“base”的所有类型信息。

function aFunction(base: object) 
  const anObject =  test:value 
  if (typeof base !== 'object')  return 

  const merged =  ...base, anObject 
  return merged

【问题讨论】:

【参考方案1】:

&lt;T extends object&gt;(base: T) 表示base 是泛型类型T

而且 TypeScript 的类型系统还不理解泛型类型。 (#10727)

解决方法:

    重构您的代码以不使用...

    等待#10727 被解析。

    更改为其他类型检查器,例如流:

Flow 报告您的代码没有错误:

/* @flow */

function aFunction<T: Object>(base: T) 
  const anObject =  test:"value" 
  if (typeof base !== 'object')  return 

  const merged =  ...base, anObject 
  return merged

【讨论】:

非常感谢,有没有推荐的方法来合并 typescript 中的对象以保留类型信息?我已经重构以断言对象,这很有效,只是感觉相当hacky。 const merge = ...base, anObject @laramie 我不知道怎么做。我会使用Object.assign 作为解决方法。【参考方案2】:

目前,泛型尚不支持传播和休息。

【讨论】:

【参考方案3】:

在第一个 sn-p 基是type T,它继承自对象。好吧,您知道在 javascript 中它不是强关系,因此不是is a 关系,所以 T 不一定是object。 T 只是原型继承自 object。而且 typescript 对泛型不了解。所以不支持传播。

在代码中 sn-p 2 base 是 object 类型的,但是 typescript 支持 object spread 和 distructuring 。 object 类型的 value 可以传播。此功能主要用于制作 object 的副本。所以这就是为什么它没有错误。

【讨论】:

这只是 TypeScript 作为 #10727 的一个弱点。

以上是关于为啥打字稿抱怨对象必须是扩展类型中的对象的主要内容,如果未能解决你的问题,请参考以下文章

打字稿中对象文字的类型安全合并

打字稿中的通用对象类型

打字稿,合并对象类型?

对象打字稿中的条件类型

打字稿检查对象中的属性是不是以类型安全的方式

如何将方法的泛型类型限制为打字稿中的对象?