我试图理解为什么我在try 基于同一类型的现有对象创建新对象时,会从Typescript中得到编译器警告.

在下面的代码中,您可以看到散布key2值会导致错误Type 'string | undefined' is not assignable to type 'string'..虽然key2是可选的,但我将object1的值分散开来,我们知道它有一个key2条目.

type Test = {
  key1: string;
  key2?: {
    key3: string;
  }
}

const object1:Test = {
  key1: "hello",
  key2: {
    key3: "hi"
  }
}

const object2:Test = {
  ...object1,
  key2: { // error here
    ...object1.key2
  }
}

类型错误:

Type '{ key3?: string | undefined; }' is not assignable to type '{ key3: string; }'.
  Types of property 'key3' are incompatible.
    Type 'string | undefined' is not assignable to type 'string'.
      Type 'undefined' is not assignable to type 'string'.(2322)

我只是想了解这里的行为,以及处理这种情况的最佳方式.

TSplayground 链接:https://www.typescriptlang.org/play?#code/C4TwDgpgBAKhDOwoF4oG8BQUoGsIgEYAuKRAJwEsA7AcwG4td8AmAfhM22zxAGYTy1eowC+GMRgDGAeyqIo0gEYArCJODE481JyaESAIgAWEADanpBgDSMezDo275+UYxQOjxGKbPlLV6vZaSDqMAHQR-moaNk4g9uiOUBFhUeoEYXaeIkA

谢谢

推荐答案

key2的类型是:

key2?: {
  key3: string;
}

这意味着key2是:

  • 允许缺席
  • 允许undefined
  • 允许为{ key3: string }(具有key3属性的对象是字符串.)

允许的是具有可选key3属性的对象.

但如果我们看看你的传播类型:

const a = { ...object1.key2 }
// { key3?: string | undefined; }

这不是key2属性的有效赋值,因为如果它是一个对象,那么它must也有一个key3属性,其值为string.


为了满足这个接口,如果key2是未定义的,则需要防止创建对象.

一种方法是:

const object2:Test = {
  ...object1,
  key2: object1.key2 && {
    ...object1.key2
  }
}

Playground

Typescript相关问答推荐

当两个参数具有相同的通用类型时,如果没有第一个参数,则递减约束默认会导致第二个参数的错误推断

TypScript ' NoInfer '类型未按预期工作

如何使类型只能有来自另一个类型的键,但键可以有一个新值,新键应该抛出一个错误

typescript抱怨值可以是未定义的,尽管类型没有定义

使用React处理Websocket数据

如何在单击停止录制按钮后停用摄像机?(使用React.js和Reaction-Media-Recorder)

TypeScrip表示该类型不可赋值

通配符路径与每条路径一起显示

我可以以这样一种方式键入对象,只允许它的键作为它的值吗?

使用订阅时更新AG网格中的行

如何在已知基类的任何子类上使用`extends`?

如何 bootstrap TS编译器为类型化属性`T`推断正确的类型?

如何过滤文字中的类对象联合类型?

将对象的属性转换为正确类型和位置的函数参数

try 使Angular依赖注入工作

在抽象类属性定义中扩展泛型类型

必需的输入()参数仍然发出&没有初始值设定项&q;错误

从以下内容之一提取属性类型

类型脚本中参数为`T`和`t|unfined`的重载函数

将带有额外id属性的Rust struct 展平回TypeScript单个对象,以返回wasm-bindgen函数