首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在React中比较两个类型化的对象(带有接口)?

如何在React中比较两个类型化的对象(带有接口)?
EN

Stack Overflow用户
提问于 2020-05-26 16:32:35
回答 3查看 774关注 0票数 1

需要获取两个对象之间已更改属性的增量(key/val)。代码是typescript。这两个对象是由相同的接口创建的。

代码语言:javascript
复制
export interface ITestObj {
   att1: string;
   att2: string[];
   att3: string;
}

我收到错误,对象的属性不能用作索引。不能做这样的事情:

代码语言:javascript
复制
if(objA['att1'] !== objB['att1']) {
}

为了解决这个问题,我尝试将接口修改为:

代码语言:javascript
复制
export interface ITestObj {
       [att1: string]: string;
       att2: string[];
       att3: string;
    }

但这是不能做到的,因为并不是所有的属性都是字符串(或数字...)。

如何获取objA和objB之间不同的属性?

非常感谢。

EN

回答 3

Stack Overflow用户

发布于 2020-05-26 16:47:01

您可以使用typeof()进行值类型比较:

代码语言:javascript
复制
if (typeof objA.att1 !== typeof objB.att1) {
    // ...
}

请参阅TypeScript文档中的typeof type guards

票数 0
EN

Stack Overflow用户

发布于 2020-05-26 17:27:06

你可以试试

代码语言:javascript
复制
if(objA.att1 !== objB.att1) {
}

但是更好的方法是使用

代码语言:javascript
复制
if(JSON.stringify(objA) !== JSON.stringify(objB)) {
}
票数 0
EN

Stack Overflow用户

发布于 2020-05-26 17:48:59

我试着在下面的代码中给出几个解决方案的细目:

代码语言:javascript
复制
type A = {
  att1: string;
  att2: string[];
  att3: string[];
};

const compare = <T extends {}>(a: T, b: T): boolean => {
  // Now there is several ways of doing this, all come with pros and cons

  // 1. If you are absolutely certain that the objects have ALL the attributes
  // from interface T (and no other attributes hidden from TypeScript)
  // you can just well use something like isEqual from lodash or similar
  // OR take the keys of one of your objects which will give you an array:
  //
  // const keys = ['att1', 'att2', 'att3']
  //
  // And you need to tell TypeScript that you are sure that these keys are exactly the ones from interface T
  // by casting the string[] (that you get from Object.keys) to K[]
  type K = keyof T;
  const keys = Object.keys(a) as K[];

  // Then finally loop over those keys and do the comparison that you want, I just sketched a thing here
  //
  // Note that to compare the string arrays you will need something more sophisticated than '==='!
  for (const key of keys) {
    if (a[key] !== b[key]) return false;
  }

  // 2. If you are not sure about what attributes there might be but the interfaces you need to compare
  // are always the same (i.e. you don't need compare() to be generic)
  //
  // In this case you can either store the keys you expect in a hard-coded array:
  type KA = keyof A;
  const hardcodedKeys: KA[] = ['att1', 'att2', 'att3'];

  // And again do your comparison here

  // You can also go fancy and use something like ts-transformer-keys:
  // https://www.npmjs.com/package/ts-transformer-keys
  // which will give you the list of keys for a small price of hooking up the TypeScript transform

  // And again do your comparison here

  return true;
};

转换不知道类型参数T是什么,因为它依赖于函数被调用的位置,所以你不能提取它的键!

它与TypeScript本身有关,你必须在那里帮它一把:

代码语言:javascript
复制
// You will need to pass the array of keys to the function explicitly
// and let TypeScript just check that what you passed actually are keys of T
const compareProperties = <T extends {}>(a: T, b: T, keys: (keyof T)[]): boolean => {
  for (const key of keys) {
    if (a[key] !== b[key]) return false;
  }

  return true;
};

同样,您可以使用ts-transformer-keys在编译时为您生成该数组。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62017787

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档