how do i add multiple assertions in typescript?

Your issue is that cell can be of type CellA which doesn’t have the property date (hence the error message you are getting). Note that the vice versa is also true, that cell doesn’t have the property text either.

Potential Solutions

1. Use an intersection type

If cell is supposed be a combination of both CellA and CellB then you can make cell of type CellA & CellB. For example:

type CellC = CellA & CellB

const cell: CellC = { date: new Date(), text: 'Hello!' }

const { date, text }
console.log(date, text)

2. Use type guards: Playground

If you have a value that you need to type check at runtime, you could use a user-defined type guard. For example, if you have a variable cell whose type you don’t know at runtime:

const cell = { text: 'Hello!' } // unknown type

function isCellA(obj: any): obj is CellA {
    if(!obj) return false
    if(!obj.text) return false
    if(typeof obj.text !== 'string') return false

    return true
}

if(isCellA(cell)) {
    // at this point the compiler recognizes that cell
    // is of type CellA
    console.log(cell.text)
}

If you need to do type checking at runtime, this is probably your best choice. It maintains type safety and helps reduce runtime errors if cell really isn’t what you expected it to be.

3. Extend another interface

This one is pretty similar to solution #1. If CellA and CellB are supposed to share some properties then one of them can extend the other, or they can extend a common interface. For example:

interface Cell {
    date: Date
}

interface CellC extends Cell {
    text: string
}

4: React component composition

If you are having this issue specifically React (as your comment states), you could consider having a separate component that returns the main component for each cell type. Example:

function ACell({ data }: { data: CellA } ) {
    return <Cell>{data.text}<Cell>
}

function BCell({ data }: { data: CellB } ) {
    return <Cell>{data.date.toString()}<Cell>
}

function Cell({ children }: { children: string }) {
    return <p>{children}</p>
}

Maybe that doesn’t meet your specific use case, but something similar could be helpful in separating logic for each type of cell between components, and sharing common logic with a third Cell component, for example.

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top