I am attempting to implement additional types within this WebSocket protocol:
type Action = {
action: "change-or-create-state";
response: string;
} | {
action: "get-state";
response: string | null;
};
/**
* map an action to its response
*/
type ActionResponse<T extends Action["action"]> = Extract<
Action,
{ action: T }
>["response"];
export async function doAction<
TAction extends Action["action"]
>(action: TAction): Promise<ActionResponse<TAction>> { /* ... */ }
I am facing difficulties with the types when it comes to actually resolving that promise, though:
// data received over websocket in reality
const someDataFromAPI: string = '"hello world"'
export async function doAction<
TAction extends Action["action"]
>(action: TAction): Promise<ActionResponse<TAction>> {
return new Promise<ActionResponse<TAction>>((resolve) => {
const jsonWithSpecificType: ActionResponse<TAction> = JSON.parse(someDataFromAPI);
/** ⚠️
Argument of type 'ActionResponse<TAction>' is not assignable to parameter of type 'ActionResponse<TAction> | PromiseLike<ActionResponse<TAction>>'.
Type 'Extract<{ action: “get-state”; response: string | null; }, { action: TAction; }>["response"]' is not assignable to type 'ActionResponse<TAction> | PromiseLike<ActionResponse<TAction>>'.
Type 'string | null' is not assignable to type 'ActionResponse<TAction> | PromiseLike<ActionResponse<TAction>>'.
Type 'null' is not assignable to type 'ActionResponse<TAction> | PromiseLike<ActionResponse<TAction>>'.(2345)
*/
resolve(jsonWithSpecificType)
})
}
Playground link here. What could be causing the issue? Using any
resolves the problem, but I would like to understand the underlying cause. My assumption is that there might be a discrepancy in maintaining the same type for TAction
within and outside the arrow function.