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.
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.
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
);