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



需要获取两个对象之间已更改属性的增量(键/值(。 代码是打字稿。 这两个对象是由同一接口创建的。

export interface ITestObj {
att1: string;
att2: string[];
att3: string;
}

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

if(objA['att1'] !== objB['att1']) {
}

为了解决这个问题,我试图将界面修改为:

export interface ITestObj {
[att1: string]: string;
att2: string[];
att3: string;
}

但这无法完成,因为并非所有属性都是字符串(或数字......

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

谢谢。

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

if (typeof objA.att1 !== typeof objB.att1) {
// ...
}

请参阅 TypeScript 文档中的类型保护。

你可以试试

if(objA.att1 !== objB.att1) {
}

更好的是使用

if(JSON.stringify(objA) !== JSON.stringify(objB)) {
}

我尝试在以下代码中分解几种解决方案:

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本身有关,你必须在那里帮忙:

// 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在编译时为您生成该数组。

最新更新