🧵👇

1. With explicit type arguments. Everything is fine.
2. With inferred type arguments. P cannot be inferred, because it does not relate to any method argument.
3. With one explicit type argument. But why is the second argument not inferred?
// ActionCreator
const incrementAction = createAction
// ActionCreator
const actionCreator2 = createAction(type);
// ActionCreator
const actionCreator3 = createAction
There is a PR for that at github.com/microsoft/Type…, but there is still discussion on what syntax to use.
Let's just assume that this is impossible and try to work around it.
Here `createAction` infers `T` and `withPayload` is called with `number` explicitly.
But this requires a change in our existing runtime code, and it is a bit weird to use.
const incrementAction = createAction("increment" as const)
Actually, our `createAction` function can take an optional second `prepare` argument to modify the payload beforehand.
Here we just create a helper fn that captures a type and returns a `prepare` function that just passes the payload through.
Next week, you will learn how you can add restrictions to your type parameters.
After all, right now you could pass any object as `T` parameter, and we don't want that.