ts-xor icon indicating copy to clipboard operation
ts-xor copied to clipboard

Putting XOR inside of a union type allows any key to be used in object

Open slavafomin opened this issue 4 years ago • 2 comments

Hello!

Thank you for this great library!

However, putting XOR inside of a union type:

type Creature = (XOR<T1, T2> | string);

allows any key to be used in objects T1 and T2:

import { XOR } from 'ts-xor';


type Person = {
  name: string;
}

type Animal = {
  nickname: string;
}

type Creature = (string | XOR<Person, Animal>);


// GOOD: doesn't throw error
const creature0: Creature = 'Krusty';

// GOOD: doesn't throw error
const creature1: Creature = {
  name: 'Homer',
};

// GOOD: doesn't throw error
const creature2: Creature = {
  nickname: 'Santa\'s Little Helper',
};

// GOOD: throws error
const creature3: Creature = {
  name: 'Homer',
  nickname: 'Santa\'s Little Helper',
};

// BAD: doesn't throw error
const creature4: Creature = {
  name: 'Homer',
  foo: true,
};

// BAD: doesn't throw error
const creature5: Creature = {
  nickname: 'Santa\'s Little Helper',
  foo: true,
};

Could you please elaborate on this behavior? Is it expected? Thanks.

slavafomin avatar Apr 02 '20 23:04 slavafomin

I'm coming on this several months later as a potential user of this library. I just tried the above code in the Typescript playground and the creature4 and creature5 examples did produce error messages for me.

mjwach avatar Dec 02 '20 20:12 mjwach

In the typescript playground I also do not see errors from assignment to the foo variable.

However, when I replaced XOR with this, it raised the proper errors for all three error cases as expected.

type XOR<A extends Object, B extends Object> =
  | (A & { [k in keyof B]?: never })
  | (B & { [k in keyof A]?: never });

Perhaps this is an alternative approach?

cefn avatar Dec 29 '20 23:12 cefn

However, when I replaced XOR with this, it raised the proper errors for all three error cases as expected.

type XOR<A extends Object, B extends Object> =
  | (A & { [k in keyof B]?: never })
  | (B & { [k in keyof A]?: never });

Perhaps this is an alternative approach?

The suggested alternative implementation of XOR fails the following tests:

image

maninak avatar Feb 10 '23 05:02 maninak

@slavafomin I can't seem to reproduce the reported issue. Everything seems to pass/error-out as expected.

image

Closing until further notice. If the issue does persist, please post a reproduction link shown in the TS Playground.

maninak avatar Feb 10 '23 05:02 maninak