To create a more versatile solution, you can pass the type guard function as a parameter. Here's how it would look:
function getTypeFromMixedList<T, U extends T>(
mixedList$: Observable<T[]>,
guard: (item: T) => item is U
): Observable<U[]> {
return mixedList$.pipe(map(items => items.filter(guard)));
}
If you're working with a discriminated union type, you can also provide the discriminant key and value to check for:
function getTypeFromDiscriminatedUnionList<
T,
K extends keyof T,
V extends (T[K]) & (string | number | undefined | null)
>(
mixedList$: Observable<T[]>,
key: K,
val: V
): Observable<Extract<T, { [P in K]?: V }>[]> {
return mixedList$.pipe(
map(items =>
items.filter(
(item): item is Extract<T, { [P in K]?: V }> => item[key] === val
)
)
);
}
You can use either approach in your specific scenario like this:
getTypeFromMixedList(of([a, b]), (x): x is TypeA => x.kind === "typeA").subscribe(
v => (dataDivA.innerHTML = JSON.stringify(v))
);
getTypeFromDiscriminatedUnionList(of([a, b]), "kind", "typeB").subscribe(
v => (dataDivB.innerHTML = JSON.stringify(v))
);
I hope this information proves helpful. Best of luck with your implementation!
Here is the Stackblitz link to the code