1

For the following example:

type Base = {
    base : string,
    count : number
}
type ExtendedA = Base & {
    special : string
}
type ExtendedB = Base & {
    hidden : number
}

function EXAMPLE (payload : ExtendedA | ExtendedB) {
    if ("special" in payload) {
        payload.special
    }
    else {
        payload.hidden
    }
}

const payload : Parameters<typeof EXAMPLE>[0] = {
    hidden : 123,
    
}

How do I ensure that special isn't also shown/allowed, since I have chosen hidden as one of my properties, which only exists in ExtendedB and not ExtendedA

playground


Extended

With a more practical example with StrictUnion, it fails when trying to pass onto other functions

type Base = {
    base : string,
    count : number
}
type ExtendedA = Base & {
    special : string
}
type ExtendedB = Base & {
    hidden : number
}
type UnionKeys<T> = T extends T ? keyof T : never;
type StrictUnionHelper<T, TAll> = 
    T extends any 
    ? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, never>> : never;

type StrictUnion<T> = StrictUnionHelper<T, T>

function SPECIAL (payload : ExtendedA) {

}
function HIDDEN (payload : ExtendedB) {

}
function EXAMPLE (payload : StrictUnion<ExtendedA | ExtendedB>) {
    if ("special" in payload) {
        SPECIAL(payload)
    }
    else {
        HIDDEN(payload)
    }
}

const payload : Parameters<typeof EXAMPLE>[0] = {
    hidden : 123,
    base : "abc",
    count : 2,
}

EXAMPLE(payload)
A. L
  • 11,695
  • 23
  • 85
  • 163
  • 1
    You need to use `StrictUnion` from [here](https://stackoverflow.com/questions/65805600/type-union-not-checking-for-excess-properties#answer-65805753). See [this](https://tsplay.dev/N5LL5w). If you provide `special` property along with `hidded` TS still allows it since this is still can be assigned to union `ExtendedA | ExtendedB` – captain-yossarian from Ukraine Aug 23 '22 at 06:16
  • @captain-yossarianfromUkraine so I can only apply strict union to the payload type? I updated the example which more closely reflects my implementation, and it seems like I can't use `StrictUnion` directly on the function's argument itself. All of the keys still show up, although exclusive keys will result in an error – A. L Aug 23 '22 at 06:35
  • You can use `StrictUnion` for explicit type of `payload` const and not for function arguments' or provide discriminant property `type: 'A'` and `type: 'B'` – captain-yossarian from Ukraine Aug 23 '22 at 07:11

0 Answers0