Please forgive my verbosity in asking this question:
A library I'm using (which is an abstraction of redux), called easy-peasy, exposes the following types to be used in conjunction with one another. The Thunk
type has several unused generic params, which seem to exist only to provide inference for the thunk
function's genreic params (which match the Thunk
type's params exactly):
export type Thunk<
Model extends object, // not used
Payload = undefined,
Injections = any, // not used
StoreModel extends object = {}, // not used
Result = any
> = {
type: 'thunk';
payload: Payload;
result: Result;
};
export function thunk<
Model extends object = {},
Payload = undefined,
Injections = any,
StoreModel extends object = {},
Result = any
>(
thunk: (
actions: Actions<Model>,
payload: Payload,
helpers: Helpers<Model, StoreModel, Injections>,
) => Result,
): Thunk<Model, Payload, Injections, StoreModel, Result>;
The recommended usage would be something like:
type Injections = {
someFunc: () => "foo";
}
const someThunk: Thunk<LocalModel, string, Injections, StoreModel, Promise<void>> = thunk(
(actions, payload, { injections, getState, getStoreState }) => {
// do something
const state = getState(); // returns local state
const storeState = getStoreState(); // returns global / store state
const foo = injections.someFunc(); // foo
}
);
However, if you try to create an alias of the Thunk
type to have a less verbose definition, all of the generic params that don't get "used" by the Thunk
type itself (Model
, StoreModel
, and Injections
), seem to get lost, and actions, injections, getState (depends on Model
type), and getStoreState
(depends on StoreModel
type) are no longer typed (they become any
).
type LocalThunk<TPayload, TResult> = Thunk<
LocalModel,
TPayload,
Injections,
StoreModel,
TResult
>;
const someThunk: LocalThunk<string, Promise<void>> = thunk(
(actions, payload, { injections, getState, getStoreState }) => {
// do something
const state = getState(); // any
const storeState = getStoreState(); // any
const foo = injections.someFunc(); // any
}
);
The best I can figure is that this is because the alias doesn't "remember" the types that don't actually get used in the Thunk
type.
I have a few workarounds, so I'm not really looking for that here. What I'm interested in is if anyone can provide a more well substantiated reason as to why this is, and if this should be considered a bug, and if perhaps TypeScript github is a better place to raise this issue.
Here's a small repro so you can see this in action: https://codesandbox.io/s/shy-worker-qpi5lr?file=/src/store.tsx
Any info or documentation to support why this doesn't work would be helpful!