2

Following is the code I'm trying to run in a typescript editor

  type ABC = {
      title: string
  }

  type DEF = {
      name: string
  }


  type XYZ = {
      desc: ABC[] | DEF[]
  }


const container: XYZ = {
    desc: [{title: 'abc'},{title: 'def'}]
}
  const { desc } = container


desc.find((t: ABC) => t.title === 'abc') 

But there is red line under find() and when i hover over it I see the following message:

This expression is not callable.Each member of the union type 
'{ <S extends ABC>(predicate: (this: void, 
value: ABC, index: number, obj: ABC[]) => value is S, thisArg?: any): S | 
undefined; (predicate: (value: ABC, index: number, obj: ABC[]) => unknown, 
thisArg?: any): ABC | undefined; } | { ...; }' has signatures, but none of
 those signatures are compatible with each other.

How do i fix this such that I don't see the squiggly line

Inigo
  • 7,889
  • 4
  • 26
  • 55
The Third
  • 717
  • 2
  • 9
  • 27

2 Answers2

1

Your problem is that the type of desc is ABC[] | DEF[].

That means you need to supply desc.find with a function that can iterate over the elements of either a ABC[] or a DEF[]. That's what the error message is telling you.

Assuming the intent of your code is to ONLY look for an ABC in desc, the following code will do so safely, first checking to make sure desc is an ABC[] instead of a DEF[]. You can also test it in TS Playground.

type ABC = {
    title: string
}

type DEF = {
    name: string
}

type XYZ = {
    desc: ABC[] | DEF[]
}

const container: XYZ = {
    desc: [{ title: 'abc' }, { title: 'def' }]
}
const { desc } = container

let result: ABC | undefined

// only do the search if desc is an ABC[]
if (desc[0] && 'title' in desc[0]) {
    // Typescript isn't smart enough to figure out that
    // desc is now guaranteed to be an ABC[], we need
    // to include a type assertion
    result = (desc as ABC[]).find((t: ABC) => t.title === 'abc')
}

console.log(result)
Inigo
  • 7,889
  • 4
  • 26
  • 55
0

I solved it by doing this

const { desc}: { desc: ABC[] } = container


desc.find((t: ABC) => t.title === 'abc') 
The Third
  • 717
  • 2
  • 9
  • 27
  • That's a hack that hides rather than solves the problem. Presumably in real code you don't know if `desc` is type `ABC[]`. – Inigo Jan 16 '22 at 20:50