Reputation: 1393
function foo<T extends object>(t: T): T {
return {
...t // Error: [ts] Spread types may only be created from object types.
}
}
I am aware that there are issues on github, but I can't figure out what is fixed and what is not and they have 2695 open issues. So I am posting here. I am using latest Typescript 2.9.2.
Should the above code not work? And how can I fix it if possible?
Upvotes: 106
Views: 168182
Reputation: 55
I had this issue with react-hook-form
I just did this:
{...(register('fieldName') as unknown as Record<any, unknown>)}
Upvotes: 2
Reputation: 675
You can use Record<string, unknown>
or an interface like the below examples:
goodsArray.map(good => {
return {
id: good.payload.doc.id,
...(good.payload.doc.data() as Record<string, unknown>)
};
});
or
goodsArray.map(good => {
return {
id: good.payload.doc.id,
...good.payload.doc.data() as Goods // 'Goods' is my interface name
};
});
Upvotes: 45
Reputation: 145880
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.
Upvotes: 6
Reputation: 474
This answer may help to fix the same problem while using angular and firestoe.
return { id: item.payload.doc.id,
...item.payload.doc.data()}
as Employee
this on will throw he same error. for fixing you have to change like this one.
return { id: item.payload.doc.id,
...item.payload.doc.data() as Employee }
Upvotes: -1
Reputation: 11115
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);
}
Upvotes: 145
Reputation: 249466
Version 3.2 of Typescript fixed this. The two PRs that improve handling of spread and rest parameters are:
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.
Upvotes: 10