#Mutually exclusive properties

12 messages · Page 1 of 1 (latest)

fiery acornBOT
#
m.a.t.t.t#0

Preview:```ts
type Base = {
id: string
}

type CaseA = Base & {
foo: string
bar: never
}

type CaseB = Base & {
foo: never
bar: number
}

type U = CaseA | CaseB

function test(u: U) {
if (u.foo) {
u.bar += 1
}
}```

acoustic falcon
#

or do I just drop the never fields? only issue then is that i have to use

if ('foo' in u)

instead of simply if (u.foo)

high mica
#

I recommend dropping the never fields, yeah.

#

Some people use this pattern when they want to be strict about disallowing both foo and bar, I would suggest a discriminated union instead.

acoustic falcon
#

ah okay, will do that.thanks! just really wish I didn't have to do property in checks

high mica
#

(The direct fix to what you're trying to do - the other fields need to be optional ?: never or ?: undefined)

acoustic falcon
#

ah how would that work?

high mica
#

The thing I'd actually suggest is a discriminated union:

fiery acornBOT
#
type Base = {
    id: string
}

type CaseA = Base & {
    kind: "A",
    foo: string
}

type CaseB = Base & {
    kind: "B",
    bar: number
}

type U = CaseA | CaseB

function test(u: U) {
    if (u.kind == "A") {
        u.bar += 1
//        ^^^
// Property 'bar' does not exist on type 'CaseA'.
    }
}
acoustic falcon
#

ohh ok thats perfect! i think in my case i could even avoid kind and just put foo: null in CaseB?

high mica
#

There's not really an advantage to adding foo: null when you're using kind.

vivid marsh
#

that's no longer a discriminated union then (if you leave out kind), it'd be basically what you're doing with never, except you'd have to explicitly add the fields with a value of null