我试图通过检查一个公共属性值来比较一个项目是否存在于另一个数组中。对于下面的代码,它会抛出以下错误:
TS2367:此条件将始终返回'false',因为类型'U[K]'和'T[K]'没有重叠。
const sourceArray = [{requestId: "1", name: "henry"},{requestId: "2", name: "bob"}]
const arrayListToCompareWith = [{requestId: "1", age: 30}, {requestId: "9", age: 40}]
const commonItems = getItemsInSourceArrayWhichArePresentInArrayToBeComparedWith(sourceArray,arrayListToCompareWith, "requestId" )
function getItemsInSourceArrayWhichArePresentInArrayToBeComparedWith<
T,
U,
K extends keyof T & keyof U,
>(
sourceArray: T[],
arrayListToCompareWith: U[],
comparisonKey: K, // "requestId"
) {
const itemsInSourceArrayWhichAreNotPresentInArrayToBeComparedWith: T[] =
sourceArray.filter((sourceArrayItem: T): boolean => {
const { [comparisonKey]: sourceArrayItemComparisonKeyValue } = sourceArrayItem; sourceArrayItemComparisonKeyValue
const itemExistsInTheArrayWeAreComparingWith: boolean =
arrayListToCompareWith.some((itemToCompareWith: U): boolean => {
const comparisonValueInItemToCompareWith = itemToCompareWith[comparisonKey]; // U[K]
const comparisonValueInSource = sourceArrayItemComparisonKeyValue; //T[K]
// TS2367: This condition will always return 'false' since the types 'U[K]' and 'T[K]' have no overlap.
const check = comparisonValueInItemToCompareWith === comparisonValueInSource;
return check;
});
return itemExistsInTheArrayWeAreComparingWith;
});
return itemsInSourceArrayWhichArePresentInArrayToBeComparedWith;
}
下面是上述代码问题的TS playground链接:
TS Playground链接运行代码
问题是你没有告诉Typescript在T
和U
之间有任何关系,特别是你没有说它们必须具有相同的属性K
的值类型。
实际上不需要第二个类型参数U
-我们需要说的是第二个数组包含具有与T
具有相同值类型的键K
的对象。可以更简单地写成Pick<T, K>
。
function filterByKey<T, K extends keyof T>(arr: T[], keysToKeep: Pick<T, K>[], key: K) {
return arr.filter(
item => keysToKeep.some(
otherItem => item[key] === otherItem[key]
)
);
}
操场上联系