'How to convert inferred String Tuple to String Union in Typescript Typings?
Goal
I am trying to make something like this:
createTaskDispatcher(["spare","not_spare"],(context,payload,dispatch)=>{
if(payload.spare){
//do something here
//dispatch ==> Dispatch<Actions>= (action:Actions)=>void;
dispatch("spare");//here should be Dispatch<"spare"|"not_spare">
}
else{
//do something here
dispatch("not_spare")
}
})
Things I'm Trying
I'm trying make it with these code below:
export type Dispatch<ActionType> = (action: ActionType) => void;
type ArrayRetreiver<A> = A extends Array<infer W> ? W : never;
export type ArrayToDispatch<A> = A extends string[]?Dispatch<ArrayRetreiver<A>>:never;
function createTaskDispatcher<P, U,C>( conditionList:U,dispatcher: (ctx: C, payload: P, dispath: ArrayToDispatch<U>) => void) {
....
}
But I get the dispatch method's parameter is string.
//the dispatch parameter: (parameter) dispatch: Dispatch<string>
let spareCheck = createTaskDispatcher( ["spare","not_spare"],(ctx, payload, dispatch) => {
});
So I use spare|not_spare like string to replace the array parameter.
export type Dispatch<ActionType> = (action: ActionType) => void;
type SplitString<S, Separater extends string = "|", AL = never> = S extends `${infer A}${Separater}${infer Rest}` ? SplitString<Rest, Separater, AL | A> : S | AL;
function createTaskDispatcher<C, P, U extends string>(conditionList: U, dispatcher: (ctx: C, payload: P, dispath: Dispatch<SplitString<U>>) => void) {
}
But I still want to know how to implement my first idea.
Summary
In a nutshell, I want to destruct the string array/tuple into string union, And the union will be the second callback's dispatch parameter's input type.
Solution 1:[1]
You can use as const to accomplish that.
type Dispatch<ActionType> = (action: ActionType) => void;
function createTaskDispatcher<ActionType, P, C>(
conditionList: readonly ActionType[],
dispatcher: (ctx: C, payload: P, dispatch: Dispatch<ActionType>) => void
) {}
const actionTypes = ['spare', 'not_spare'] as const;
createTaskDispatcher(actionTypes, (ctx, payload, dispatch) => {
dispatch('not_spare')
})
Note I removed ArrayRetriever because TS has built-in support to accomplish what you were trying to do.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Amiratak88 |
