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
CodePudding user response:
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)
CodePudding user response:
I solved it by doing this
const { desc}: { desc: ABC[] } = container
desc.find((t: ABC) => t.title === 'abc')
