typescripteslintlint

TS spells an error with Omit and I do not understand why


Can someone explain please, why I receive an error with Omit even if I do not change the field, noticed in error text?

The code:

enum Status {
    ACTIVE = 'active',
    PAUSED = 'paused',
}

type Camp = {
    id: number
    uuid: string
    status: Status
} & (
    |{
        owned: false
        name: string
        surname: string
    } | {
        owned: true
    }
)

// No errors
const data1: Camp[] = [] // not correct type notation
const result1: Camp[] = data1.map((item) => {
    return {
        ...item,
        status: item.status === 'suspended' as Status ? Status.PAUSED : item.status // wanna get rid of 'as Status'
    }
})

// Linter spells an error:
// - Types of property 'owned' are incompatible.
// - Type 'boolean | undefined' is not assignable to type 'true | undefined'.
// - Type 'false' is not assignable to type 'true'.ts(2322)
const data: Array<Omit<Camp, 'status'> & {status: Status | 'suspended'}> = []
const result: Camp[] = data.map((item) => {
    return {
        ...item,
        status: item.status === 'suspended' ? Status.PAUSED : item.status
    }
})

Have no idea, why this error fires, cuz I do not even touch owned property...


Solution

  • You can use an extra generic param to extends the status of Camp:

    Playground

    enum Status {
        ACTIVE = 'active',
        PAUSED = 'paused',
    }
    
    type Camp<S extends string = never> = {
        id: number
        uuid: string
        status: Status | S
    } & (
        |{
            owned: false
            name: string
            surname: string
        } | {
            owned: true
        }
    )
    
    
    const data: Camp<'suspended'>[] = []
    const result: Camp[] = data.map((item) => {
        return {
            ...item,
            status: item.status === 'suspended' ? Status.PAUSED : item.status
        }
    })