Typescript: Spread types may only be created from object types

Solution 1:

This is fixed in TypeScript Version 3.2. See Release Notes.


Looks like spread with a generic type isn't supported yet, but there is a GitHub issue about it: Microsoft/TypeScript#10727.

For now you can either use type assertion like @Jevgeni commented:

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

or you can use Object.assign which has proper type definitions.

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

Solution 2:

You can use blank curly brackets {} or an interface like below examples:

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

or

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

Solution 3:

Version 3.2 of Typescript fixed this. The two PRs that improve handling of spread and rest parameters are:

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

You can try it out now using npm install [email protected].

With 3.2 your code works as is.

Version 3.2 has been released on November 29th, 2018, you can read more about it here.

Solution 4:

If you are still getting this error post version 3.2 then you probably have a type error 'upstream' resulting in an object being unknown instead of an actual object. For instance if you have the spread expression { ...getData() } but your getData function has a compile error you may see this error.

So check for any compiler errors in your browser console because the final error may be misleading.