首页 > 解决方案 > 在没有密钥存在检查的情况下合并 TypeScript 中的两个对象

问题描述

我想合并两个对象。将默认值作为基本模型并替换下一个对象的所有值。但是 TypeScript 会为我的类型抛出错误。

我有这个对象:

const grades = {
  "grade": {
    "level": 1,
    "state": 1,
    "grade": "B"
  },
  "level": {
    "id": 1,
    "name": "Level 1"
  }
}

我为他们准备了一个类型:

export type UserLGType = typeof grades
export type GradeType = typeof grades.grade

现在在其他地方我声明一个像这样的变量:

const x: UserLGType = grades // get all values as default

现在,我的问题是,我从数据库中获取了一些值。让我们假设这是来自 db 的等级:

const gradesFromDB: any = { "level": 2 }

如您所见any,它仅包含level2

让我们合并默认值:

x.grade = {...x.grade, gradesFromDB}

预期结果:

   {
      "grade": {
        "level": 2, // see here..
        "state": 1,
        "grade": "B"
      },
      "level": {
        "id": 1,
        "name": "Level 1"
      }
    }

实际结果:

Object literal may only specify known properties, and 'gradesFromDB' does not exist in type '{ "level": number; "state": number; "grade": string; }'.

在此处查看演示https ://repl.it/repls/BusyAccomplishedData

现在,我怎样才能合并这两个对象?我可以做循环,但它会是一个大数据集,所以有没有一种快速和安全的方法来做到这一点?只需获取默认值,然后从数据库中更改值。

标签: typescriptecmascript-6

解决方案


你需要这样做:

x.grade = {...x.grade, ...gradesFromDB}

GradesFromDB 上的扩展运算符将属性提取到新对象中。正如您所拥有的那样,您正在为该值的新对象分配一些属性“gradesFromDB”。

但是,你应该停止做这些简短的类型声明并编写实际的接口:

export interface GradeType {
  level: number;
  state: number;
  grade: string; // maybe better like: 'A'|'B'|'C' etc 
}

export interface UserLGType {
  grade: GradeType;
  level: {
    id: number;
    name: string;
  }
}

然后使用它们输入内容:

const DEFAULT_GRADE: UserLGType = {
  "grade": {
    "level": 1,
    "state": 1,
    "grade": "B"
  },
  "level": {
    "id": 1,
    "name": "Level 1"
  }
}

const gradesFromDB: Partial<GradeType> = { "level": 2 }

推荐阅读