Last updated: Feb 28, 2024
Reading time·3 min
The "Spread types may only be created from object types" error occurs when we try to use the spread syntax with a value that is possibly not an object.
To solve the error, use a conditional to make sure the value is an object before using the spread syntax.
Here is an example of how the error occurs.
type Person = { name: string } | undefined; const val1: Person = undefined; // ⛔️ Error: Spread types may only be created from object types.ts(2698) console.log({ ...val1 });
The val1
variable can either store an object or an undefined
value.
Trying to use the spread syntax with an
undefined
value causes the error.
Here is another example.
const val2 = false; // ⛔️ Error: Spread types may only be created from object types.ts(2698) console.log({ ...(val2 && { name: 'Bobby Hadz' }) });
false
, so we try to use the spread syntax with a boolean
value and get the error.The spread syntax (...) can only be used with object types.
To solve the error, make sure the value we are using the spread syntax with is an object.
If you are absolutely positive the value is an object and TypeScript is getting confused, use a type assertion.
const obj1 = Math.random() > 0.5 ? { name: 'Bobby Hadz' } : true; const result = { ...(obj1 as Record<string, unknown>) };
Type assertions are used when we have information about the type of a value that TypeScript can't know about.
We effectively tell TypeScript that obj1
will be an object and not to worry
about it.
Another approach to solving the error is to use a type guard.
type Person = { name: string } | undefined; const val1: Person = Math.random() > 0.5 ? undefined : { name: 'Bobby Hadz' }; const result = { ...(typeof val1 === 'object' ? val1 : {}) }; console.log(result.name?.toUpperCase());
The val1
variable can either have a value of undefined
or be an object.
We used the ternary operator with the spread syntax to provide an
empty object as a fallback value in
case the val1
variable doesn't store an object.
undefined
value.Object.assign()
method insteadIf you don't like this approach, try using the Object.assign()
method, which
is more forgiving.
const result = Object.assign({}, false, true, undefined, null, 0, { name: 'Bobby Hadz', }) as { name: string }; console.log(result.name); // 👉️ "Bobby Hadz"
The argument we passed to the Object.assign() method are:
However, we can pass pretty much any value to the Object.assign()
method
without TypeScript yelling at us.
Notice that we used a type assertion to type the result
variable. Had we not
done this, it would have been typed as any
.
You can learn more about the related topics by checking out the following tutorials: