I have the following example to illustrate what I'm trying to get.
const v1: { type: "S"; payload: string } = { type: "S", payload: "test" };
const v2: { type: "N"; payload: number } = { type: "N", payload: 123 };
type Actions = typeof v1 | typeof v2;
const findByType = <A extends Actions>(type: A["type"]) => (
action: Actions
): action is A => action.type === type;
const filterWithBothNameAndType = [v1, v2].filter(findByType<typeof v1>("S"));
console.log(filterWithBothNameAndType[0].payload.trim());
const findByTypeDoesntWork = <A extends Actions, T extends A["type"]>(type: T) => (
action: Actions
): action is A => action.type === type;
const filterWithJustType = [v1, v2].filter(findByTypeDoesntWork("S"));
console.log(filterWithJustType[0].payload.trim());
typescript playground
I have function findByType
that has right type information and I have function filterWithJustType
that has api that I like, but it loses type information. I want api to be just filter("S")
without passing generic type. So far it looks like it will only work with classes and instaceof
but I wanted to make it work with plain objects.
You can use Exclude
or Extract
as mentioned by the docs, for example:
type T00 = Exclude<"a" | "b" | "c" | "d", "a" | "c" | "f">; // "b" | "d"
type T01 = Extract<"a" | "b" | "c" | "d", "a" | "c" | "f">; // "a" | "c"
type T02 = Exclude<string | number | (() => void), Function>; // string | number
type T03 = Extract<string | number | (() => void), Function>; // () => void
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With