1

How does typescript define multiple type arrays? And array item is one of them.

interface A {
    m: string,
    n: number
}

interface B {
    x: boolean
    y: number[]
}

type C = A | B

const arr: C[] = [
    {m: '1', n: 1, x: true}
]

I want array item is A or B type, only match one of them, like this:

const arr: C[] = [
    {m: '1', n: 1}
]

// or
const arr: C[] = [
    {x: true, y: [1,2,3]}
]

2 Answers2

1

In order to achieve it, you need to make this union more strict.

interface A {
    m: string,
    n: number
}

interface B {
    x: boolean
    y: 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;

// credits goes to https://stackoverflow.com/questions/65805600/type-union-not-checking-for-excess-properties#answer-65805753
type StrictUnion<T> = StrictUnionHelper<T, T>

type C = StrictUnion<A | B>

const arr1: C[] = [
    { m: '1', n: 1, x: true } // expected error
]

const arr2: C[] = [
    { m: '1', n: 1 } // ok
]


const arr3: C[] = [
    { x: true, y: [1, 2, 3] }, // ok
    { m: '1', n: 2 }
]

Playground

Please see related examples in my blog

0

If both the property names are same in the interface, then it will make sure that you can not mix them two. It also usually not make sense to create a union of two interfaces that do not have anything in common.

   interface A {
    m: string,
    n: number
}

interface B {
    m: boolean
    n: number[]
}

type C = A | B


// no error
const arr: C[] = [
    {m: '1', n: 1}
]

// error (you cant mix both, it has to be one or the other)
const arr1: C[] = [
    {m: '1', n: [1]}
]
vaira
  • 2,191
  • 1
  • 10
  • 15