Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to properly find array element and cast when array has union types and generics?

I have the following type declarations:

types.ts:


type ItemKind = 'A' | 'B';

type ValidItem<TItemKind extends ItemKind = ItemKind> = {
    readonly type: TItemKind;
    readonly id: number;
};

type EmptyItem<TItemKind extends ItemKind = ItemKind> = {
   readonly type: `empty-${TItemKind}`;
};

export type Item = ValidItem | EmptyItem;

Now, given an array of Items I want to find an item element by their id property and access the value.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I’m able to provide a predicate function that finds the element but I haven’t been able to figure out how to use and cast the object once the match happens.

index.ts:

import { type Item } from './types';

const items: Items[] = [
    {type: 'A', id: 42},
    {type: 'empty-A'},
    {type: 'empty-B'}
];

console.debug('Items', items);

const targetId = 42;
const item = items.find((item) =>
  item.type === 'A' && item.id === targetId // This works
);

if (item) {
   console.debug('Item', item);

   // typecast and access id property??
   // i.e. 
   // console.debug('Id', item.id); // this gives me error
}

You can run it like this:

$ npx ts-node index.ts

Items [ { type: 'A', id: 42 }, { type: 'empty-A' }, { type: 'empty-B' } ]
Item { type: 'A', id: 42 }

Any help is greatly appreciated. I’m unable to change the type structure or declarations.

>Solution :

You can refine the item type by adding a type assertion to the callback:

const item = items.find((item): item is Item & {type: 'A'} =>
  item.type === 'A' && item.id === targetId
);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading