typescript - Type-definisjon for overlappende typer
Jeg vil gjerne lage typedefinisjonen for en funksjon som tar to objekter av ulik type, men med et felles sett av nøkler:
function myFunc(left, right, keys) {
// simplified:
for (const key of keys) {
console.log(key, left[key] === right[key])
}
return { left, right }
}
const left = {a: 1, b: 2}
const right = {b: 2, c: 3}
myFunc(left, right, ["b"])
Denne tilnærmingen fungerer, men endrer typen til den returnerte right, noe som skaper problemer i koden etter funksjonskallet:
function myFunc<
Left,
Keys extends keyof Left
>(
left: Left,
right: Pick<Left, Keys>,
keys: Keys[],
): {
left: Left
right: Pick<Left, Keys>
} {
// ...
}
Jeg vil at returtypen skal være den samme:
function myFunc<
Left,
Right extends Pick<Left, Keys>,
Keys extends keyof Left & keyof Right
>(
left: Left,
right: Right,
keys: Keys[]
): {
left: Left
right: Right
} {
// ...
}
Men nå får jeg klagen om at typene Left[Keys] og Right[Keys] ikke overlapper. Noe jeg ikke helt forstår.
Noen hint eller ideer?
Svar #1
En rar løsning, men det ser ut til å fungere i det enkle eksemplet.
Lekplasslink
function myFunc<
L extends Pick<R, (keyof R & keyof L)>,
R extends Pick<L, (keyof R & keyof L)>,
K extends (keyof R & keyof L)>
(left: L, right: R, keys: K[]): { left: L, right: R }
{
for (const key of keys) {
console.log(key, left[key] === right[key])
}
return { left, right }
}
const left = { a: 1, b: 2, c: 4 };
const right = { b: 2, c: 3, d: 5 };
// Work:
myFunc(left, right, [ 'b' ]);
myFunc(left, right, [ 'b', 'c' ]);
// Error: Type '<>' is not assignable to type '"b" | "c"'.
myFunc(left, right, [ 'a' ]);
myFunc(left, right, [ 'd' ]);
myFunc(left, right, [ 'z' ]);
Det ser imidlertid ut til å ha noen problemer hvis typene til verdiene som tilsvarer de overlappende nøklene ikke samsvarer. Det kan være en vanskelig måte å fikse det på.
Alt i alt kan det kanskje være best å slå av typetesting for den ene ===-linjen hvis mulig.
