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.

Relaterte artikler