I'm new to typescript and I'm trying to figure out how to type a specific generic object so that I can have any key + object in the interface
. This is a ReactNative Tutorial that I am doing however it's not in typescript but I wanted to transfer it to that since I'm already experienced with ReactJS and Javascript.
So I have 2 files.
Generic createDataContext
which creates any data context for me:
createDataContext.tsx
import React, { useReducer, Reducer } from 'react'interface DataContext<State> { state: State}export default <State, ActionTypes, Actions>( reducer: Reducer<State, ActionTypes>, actions: Actions, initialState: State) => { const Context = React.createContext<DataContext<State>>({ state: initialState }) const Provider: React.FC = ({ children }) => { const [state, dispatch] = useReducer(reducer, initialState) const boundActions: { string?: () => void } = {} for (let key in actions) { boundActions[key] = actions[key](dispatch) } return (<Context.Provider value={{ state, ...boundActions }}> {children}</Context.Provider> ) } return { Context, Provider }}
And my first class using it:
BlogContext.tsx
import BlogPost from '../models/BlogPost'import reducer from './BlogContextReducer'import { BLOG_CREATE, BlogActionType } from './BlogContextActions'import createDataContext from './createDataContext'import { Dispatch } from 'react'interface BlogActions { addBlogPost: (dispatch: Dispatch<BlogActionType>) => () => void}const addBlogPost = (dispatch: Dispatch<BlogActionType>) => { return () => { dispatch({ type: BLOG_CREATE }) }}export const { Context, Provider } = createDataContext< BlogPost[], BlogActionType, BlogActions>(reducer, { addBlogPost }, [])
Supporting Class
BlogContextActions.tsx
import BlogPost from '../models/BlogPost'export const BLOG_CREATE = 'BLOG_CREATE'export const BLOG_UPDATE = 'BLOG_UPDATE'export const BLOG_DELETE = 'BLOG_DELETE'interface BlogCreateAction { type: typeof BLOG_CREATE // payload: BlogPost}interface BlogUpdateAction { type: typeof BLOG_UPDATE // payload: BlogPost}interface BlogDeleteAction { type: typeof BLOG_DELETE // payload: BlogPost}export type BlogActionType = | BlogCreateAction | BlogUpdateAction | BlogDeleteAction
The issues I'm having are:1. I'm unsure how to declare the BlogActions
(generic Actions
in my createDataContext
) so that I can have it have any key in the object and loop over the key values in order to inject the dispatch (as suggested by the tutorial). 2. The for loop
const boundActions: { string?: () => void } = {}for (let key in actions) { boundActions[key] = actions[key](dispatch)}
is giving an issue because I don't have BlogActions properly typed such that I can have any key/value pair within the interface
and the type const boundActions: { string?: () => void } = {}
might even be wrong. I'm unsure because this is my first attempt at Typescript
.
My ultimate goal is to have Actions
generic be able to have any object passed in with any key that conforms to property: (dispatch: Dispatch<ActionTypes>) => () => void
Thanks in advance.