I have an array of objects, and I want the selected object to always be first. Then, if the object has a role
=== External
but it's not selected, I want that to always by last. If it doesn't match either, it's just in between the two.
const exampleObj = [
{ role: 'other', selected: false },
{ role: 'External', selected: false },
{ role: 'External', selected: false },
{ role: 'other', selected: true },
{ role: 'other', selected: false },
]
This works:
exampleObj.sort((a, b) => {
if (!a.selected && b.selected) return 1
if (a.selected && !b.selected) return -1
if (!a.role !== 'External' && b.role !== 'External') return 1
if (a.role !== 'External' && !b.role !== 'External') return -1
return 0
But I'm getting the prettier error
TS2367: This condition will always return 'true' since the types 'boolean' and 'string' have no overlap.
108 | if (!a.selected && b.selected) return 1
109 | if (a.selected && !b.selected) return -1
> 110 | if (!a.role !== 'External' && b.role !== 'External') return 1
| ^^^^^^^^^^^^^^^^^^^^^^
111 | if (a.role !== 'External' && !b.role !== 'External') return -1
112 | return 0
113 | })
TS2367: This condition will always return 'true' since the types 'boolean' and 'string' have no overlap.
109 | if (a.selected && !b.selected) return -1
110 | if (!a.role !== 'External' && b.role !== 'External') return 1
> 111 | if (a.role !== 'External' && !b.role !== 'External') return -1
| ^^^^^^^^^^^^^^^^^^^^^^
112 | return 0
113 | })
114 | : []
But if I remove those 2 lines, it's obviously not going to push the External
to the end. What am I missing here?
You could use a.role === 'External' && b.role !== 'External'
instead
!a.role !== 'External'
is same as false !== 'External'
because !a.role
will be evaluated first and the result is compared to the string.