传播类型只能从 TS 中的对象类型创建

Spread 类型只能从 TS 中的对象类型创建

Spread types may only be created from object types in TS

当我们尝试将扩展语法与可能不是对象的值一起使用时,会出现“扩展类型只能从对象类型创建”错误。

要解决该错误,请在使用扩展语法之前使用条件来确保该值是一个对象。

下面是错误如何发生的示例。

索引.ts
type Person = { name: string } | undefined; const val1: Person = undefined; // ⛔️ Error: Spread types may only be created from object types.ts(2698) console.log({ ...val1 });

变量val1可以存储对象或undefined值。

尝试将扩展语法
一起使用
undefined会导致错误。

这是另一个例子。

索引.ts
const val2 = false; // ⛔️ Error: Spread types may only be created from object types.ts(2698) console.log({ ...(val2 && { name: 'Bobby Hadz' }) });
在第二个示例中,表达式的计算结果为false,因此我们尝试使用带boolean值的扩展语法并得到错误。

扩展语法 (…) 只能用于对象类型。

在使用扩展语法之前确保该值是一个对象

要解决该错误,请确保我们使用扩展语法的值是一个对象。

如果您绝对肯定该值是一个对象并且 TypeScript 感到困惑,请使用
类型断言

索引.ts
const obj1 = Math.random() > 0.5 ? { name: 'Bobby Hadz' } : true; const result = { ...(obj1 as Record<string, unknown>) };

当我们有关于 TypeScript 不知道的值类型的信息时,使用类型断言。

我们有效地告诉 TypeScript 这obj1将是一个对象而不用担心它。

除非您绝对确定该值属于预期类型,否则不应使用此方法。

使用类型保护来解决错误

解决错误的另一种方法是使用
类型保护

索引.ts
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());

变量val1可以是一个对象,也可以undefined是一个对象。

我们使用带有扩展语法的三元运算符来提供一个
空对象作为备用值,以防val1变量不存储对象。

这让 TypeScript 很高兴,因为我们没有机会尝试将扩展语法与undefined值一起使用。

改用Object.assign()方法

如果您不喜欢这种方法,请尝试使用Object.assign()更宽容的方法。

索引.ts
const result = Object.assign({}, false, true, undefined, null, 0, { name: 'Bobby Hadz', }) as { name: string }; console.log(result.name); // 👉️ "Bobby Hadz"

我们传递给Object.assign()方法的参数

是:

  1. the target object – the object to which the provided properties will be
    applied
  2. the source object(s) – one or more objects that contain the properties we
    want to apply to the target object
The first argument you pass to the method must be an empty object because that’s where the properties of the source objects will be merged.

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.

# Additional Resources

You can learn more about the related topics by checking out the following
tutorials: