用于比较(和更新)Typescript中对象的某些字段的类型定义
我想比较和分配两个对象的某些字段,比如:用于比较(和更新)Typescript中对象的某些字段的类型定义,typescript,typescript-generics,typing,Typescript,Typescript Generics,Typing,我想比较和分配两个对象的某些字段,比如: const left = { a: 1, ignored: 5, something: 7 }; const right = { a: 2, ignored: 6, else: 8, id: 18 }; 我想调用leftToRight(left,right,['a']),然后right应该是: { a: 1, ignored: 6, id: 18 } 我想调用其他函数并传递right.id,我知道它确实存在于第二个参数中 我目前的做法是: leftT
const left = { a: 1, ignored: 5, something: 7 };
const right = { a: 2, ignored: 6, else: 8, id: 18 };
我想调用leftToRight(left,right,['a'])
,然后right
应该是:
{ a: 1, ignored: 6, id: 18 }
我想调用其他函数并传递right.id,我知道它确实存在于第二个参数中
我目前的做法是:
leftToRight(left, right, keys) {
let changed = false;
for (const key of keys) {
if (!Object.is(left[key], right[key])) {
right[key] = left[key];
changed = true;
}
}
doSomething(right.id)
return changed
}
我正在努力找到合适的类型定义:-(
初步做法:
leftToRight<T>(left: T, right: T, keys: Array<keyof T>): boolean
导致right[key]=left[key]
第三次尝试:
leftToRight<T>(left: T, right: T & {id: number}, keys: Array<keyof T>): boolean
leftToRight<T, U extends {id: number}>(left: T, right: U, keys: Array<keyof T & keyof U>): boolean
leftToRight(左:T,右:U,键:数组):布尔值
再次导致赋值
right[key]=left[key]
出错,因为类型T和U可能完全不相关。尝试left:Partial
,并断言left[key]
没有用定义!
:
const left={a:1,忽略:5};
const right={a:2,忽略:6,id:18};
函数leftToRight(左:部分,右:T,键:数组){
让改变=错误;
for(键的常数键){
如果(!Object.is(左[键]、右[键]){
右[键]=左[键]!;
更改=正确;
}
}
//doSomething(右.id)
换回
}
编辑:
您已经澄清了您的需求,即左
和右
可能各自具有其他属性中不存在的属性。要处理此场景,我们需要两种泛型类型
Right
是一个包含id
的对象。我们希望所选的键同时出现在Left
和Right
中,并且我们希望它们具有相同的值类型。
我将通用键
定义为右
键的任何子集。我将左
定义为包含所有这些键的右
的子集
function leftToRight<Right extends {id: number}, Keys extends keyof Right>(
left: Pick<Right, Keys>, right: Right, keys: Keys[]
) {
let changed = false;
for (const key of keys) {
if (!Object.is(left[key], right[key])) {
right[key] = left[key];
changed = true;
}
}
doSomething(right.id)
return changed
}
是
id
字段应该是string
还是number
?我更正了这个问题。它是一个数字。我会使用leftToRight(left:T,right:T&{id:number},keys:Array):布尔值
(right as T)[key]=left[key]或类似的方法来消除该错误;我正在寻找编译器在将T[keyof T]
分配给(T&{id:number})[keyof T])
时出现问题的原因,但我还没有找到任何东西。如果我使用:函数leftToRight(左:部分,右:T,键:数组)
,这似乎是可行的。你知道如何避免非空断言吗?不知道你避免非空断言的动机是什么,所以我不知道这是否更好,但你可以将左
转换为t
。示例:right[key]=(left as T)[key]
我想避免我的衣帽匠抱怨;-)以及在运行时检测到可能在编译期间检测到的错误的情况(在严格的空检查模式下)。在这种情况下,left[key]
是未定义的,因此,right[key]将是未定义的,如果后续代码没有预料到这一点,则可能会导致问题。然而,这可能是一个学术问题。所以,谢谢你的回答。它做它应该做的:)谢谢你的解决方案。我的问题不够清楚(将添加):left
不一定具有right
的所有属性(反之亦然)。所以right
始终具有id
,left
和right
具有任何属性,并且键
只能是共享属性,对吗?我们需要(至少)两个泛型,但我想我能做到。我看看。。。
function leftToRight<Right extends {id: number}, Keys extends keyof Right>(
left: Pick<Right, Keys>, right: Right, keys: Keys[]
) {
let changed = false;
for (const key of keys) {
if (!Object.is(left[key], right[key])) {
right[key] = left[key];
changed = true;
}
}
doSomething(right.id)
return changed
}
function leftToRight<Right extends {id: number}>(
left: Omit<Right, 'id'>, right: Right, keys: (Exclude<keyof Right, 'id'>)[]
) {
let changed = false;
for (const key of keys) {
if (!Object.is(left[key], right[key])) {
right[key] = left[key];
changed = true;
}
}
doSomething(right.id)
return changed
}