Dynamic function arguments with GENERICS - Advanced TypeScript

preview_player
Показать описание
Become a TypeScript Wizard with Matt's upcoming TypeScript Course:

Follow Matt on Twitter

Рекомендации по теме
Комментарии
Автор

This is enough to make a grown man cry.

ward
Автор

Awesome video! As a beginner developer on TS I've got stunned by these ideas and by seeing reflected the real power or robustness that Typescript can offer to your code! Amazing 🎉

thiagoneres
Автор

I spent many hours a while back trying to figure this one out! I have at least four places in my current codebase that could use this. Great video!

texoport
Автор

Man! Why is this so awesome?!?! Big thanks for sharing AND making it so easy to understand!

jennifershen
Автор

This is simply mind blowing technique.
Thank you Matt for everything you are doing. Every single video of yours is like a piece of wizardry, a potion that makes me a superhero

RomanOstolosh
Автор

This is great, been experimenting with generic void types as optional args, failed miserably haha

jam-trousers
Автор

This is crazy i just had this problem and solved it with function overloads generics and some helper types, googled an eternity how to do this better without results and a few days later this just pops up in my feed. Worked first try, youre a legend!

avaze
Автор

My gosh, it's exactly what I was trying to achieve recently and failed! This is super useful. Thank you, man!

anton.sokol
Автор

I love this video format. Short video, with bits of knowlade. I've subscribed hoping I will be able to learn more TS with you, one small bit at a time :)

noisypl
Автор

Based on this video, I created code that specifically changes the return type. I have the following union type and wanted to narrow down the type of the returned array depending on whether it's 'title' or 'body'.

export type IndexMap =
| { type: 'title'; keyword: string; target: Title }
| { type: 'body'; keyword: string; target: Body }

Therefore, I defined the return type as follows:

function searchAt<T extends IndexMap['type']>(
content: string
): Extract<IndexMap, { type: T }>['target'][] {
return []
}

If the type is 'title', it returns a Title[] and if it is 'body', it returns a Body[].

returns Title[]
searchAt<'body'>('....') returns Body[]

yeorinimsida
Автор

I just don't get why we need to use Extract. will not that result the same as Event? I think this also does the job:
function sendEvent<TEvent extends Event>(
...args: TEvent extends {payload: infer TPayload} ? [type: TEvent["type], payload: TPayload]: [type: TEvent["type"]]
)
Or am I missing something?

giodefreitas
Автор

Very useful . I will share with my friend

somebody-
Автор

This is really nice and elegant for the consumer, however there is a major problem with how you have set this up, which you didn't run into since you didn't actually write any code inside the function. The problem is that TypeScript always thinks the payload is of the `unknown` type, even after type guarding the first argument. I tried a different approach but still didn't get it to work properly. I have solved this in the past, though I'd have to look up how I did it, it's been a couple years. It certainly wasn't as elegant as this.

Matt
Автор

I subscribed please teach me your voodoo. Self taught in the industry now for 5 years transitioned to backend 2 years ago. So much to learn.

gustavcoetzee
Автор

Very cool, very interesting!
My question would be: what is the advantace of this syntax over passing an object in the form of:

type Event = {
type: "LOG_IN"
payload: any
} |
{ type: "SIGN_OUT" }

function sendEvent(event: Event): void {
return
}

sendEvent({ type: "LOG_IN", payload: "" })

sendEvent({ type: "SIGN_OUT" })

in this case, TypeScript would not let me append any payload on a function calling SIGN_OUT promting me that 'payload' does not exist in type '{ type: "SIGN_OUT"; }'.
Or is there something to this that I'm missing completely?

Espere
Автор

Ohh noo this one looks really bad to maintain, what if you have multiple args

alkolaqi
Автор

Args variable inside function is of type `(parameter) args: [type: Type] | [type: Type, payload: unknown]`. Why doest TS infer the type of payload as `unknown`?

ГерриПитт
Автор

Why this one does not seem to work? It is pretty similar:

const sendEvent = <T extends Event>(
...args: Extract<Event, { type: T["type"]}> extends {payload: infer TPayl}
? [type: T["type"], payload: TPayl]
: [type: T["type"]]
) => {};

letmein
Автор

Doesn’t this make code much harder to read and understand if you are not super familiar with Typescripts internals and quirks

pratikchakravorty
Автор

How to get args type inside function?

const sendEvent2 = <Type extends Event["type"]>(
...args: Extract<Event, { type: Type }> extends { payload: infer TPayload }
? [type: Type, payload: TPayload]
: [type: Type]
) => {
const eventType = args[0];
const payload = args[1]
};

eventType has proper type but payload type is unknown

PadamShrestha-qotu