How can I test a property on an object that may be of two different types using Jest and TypeScript?

I have a function getFruit() that returns two possible types, Banana | Apple.

I have a jest unit test that includes a test for a property that exists on one of the types, but not the other. In this case, Banana has the property peel but Apple does not.

test(`gets a banana`, () => {
  const fruit = getFruit(id)
  expect(fruit?.peel).toBeDefined();
})

I am content that fruit?.peel may not be defined when it is first referenced, as I am testing for fruit?.peel being defined in the same line.

However TS marks the fruit?.peel line as having an error:

Property 'peel' does not exist on type 'Banana | Apple'.
  Property 'peel' does not exist on type 'Apple'

How can I test a property on an object that may be of two different types using Jest and TypeScript?

I know I can disable the TS compiler with a ts-ignore, but I am hoping for a fix rather than a workaround.

>Solution :

While TypeScript won’t let you access a property that isn’t known to exist, it will let you check for its existence with the in operator:

expect('peel' in fruit).toEqual(true);

Or as jonrsharpe points out, it may be better to do this:

expect(fruit).toHaveProperty('peel');

which in the failing case outputs:

    expect(received).toHaveProperty(path)

    Expected path: "peel"
    Received path: []

    Received value: {"cultivar": "braeburn"}

rather than:

    expect(received).toEqual(expected) // deep equality

    Expected: true
    Received: false

Leave a Reply