Skip to content

Instantly share code, notes, and snippets.

@gtkatakura
Last active May 7, 2018 00:51
Show Gist options
  • Save gtkatakura/b0f805c89fa9e6afd428ddec4be699a7 to your computer and use it in GitHub Desktop.
Save gtkatakura/b0f805c89fa9e6afd428ddec4be699a7 to your computer and use it in GitHub Desktop.
TypeScript + Reducers
type ThemeColor = string;
type Theme = { id: number, color: ThemeColor }
type State = { themes?: [Theme] }
type ExtractFirstArgument<T> =
T extends (T1: infer T1) => infer R
? (T extends (t1: infer T1, t2: infer T2, t3: infer T3) => infer R
? Extract<T2, undefined> extends never
? () => R
: (Extract<T3, undefined> extends never
? (t2?: T2) => R
: (t2?: T2, t3?: T3) => R
)
: any
)
: T extends (T1: infer T1, t2: infer T2) => infer R
? (T extends (t1: infer T1, t2: infer T2, t3: infer T3) => infer R
? Extract<T3, undefined> extends never
? (t2: T2) => R
: (t2: T2, t3?: T3) => R
: any
)
: T extends (T1: infer T1, t2: infer T2, t3: infer T3) => infer R
? (t2: T2, t3: T3) => R : any;
// Se preferir deixar mais semântico a leitura
// visto que isso somente vai ser usado para reducers
type ExtractFirstArgumentForReducers<T> =
T extends (state: infer T1) => infer R ? () => R :
T extends (state: infer T1, payload: infer T2) => infer R ? (payload: T2) => R :
T extends (state: infer T1, payload: infer T2, metadata: infer T3) => infer R ? (payload: T2, metadata: T3) => R : any;
const reducers = {
setTheme(state: State, payload: ThemeColor, metadata: number): Theme {
return {} as Theme;
}
}
type Reducers = {
[P in keyof typeof reducers]: ExtractFirstArgumentForReducers<typeof reducers[P]>;
}
const example = (reducers: Reducers) => {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment