打字稿和上下文 API

Typescript and Context API

我正在尝试在应用程序中同时实施 Typescript 和 Context API。我面临着将 deleteMovie 和 addMovie 的功能实现到 MovieContext.Provider 的值属性中的问题。

这是我收到的错误:

Type '{ movies: MovieAttribute[]; deleteMovie: (id: number) => void; addMovie: (id: number, title: string) => void; }' is not assignable to type '{ movies: { id: number; title: string; }[]; }'.
  Object literal may only specify known properties, and 'deleteMovie' does not exist in type '{ movies: { id: number; title: string; }[]; }'.ts(2322)
index.d.ts(337, 9): The expected type comes from property 'value' which is declared here on type 'IntrinsicAttributes & ProviderProps<{ movies: { id: number; title: string; }[]; }>'

根据我从错误中了解到的情况,我说我尚未声明我的提供者的值不包含 'function type' 是否正确?如果是这样,我该如何修改这个问题?

MovieContext.tsx

import React, { createContext, useReducer } from 'react';
import MovieReducer from '../reducers/MovieReducer';

const initialState = { 
    movies: [
        {
            id: 1,
            title: "King Kong"
        },
        {
            id: 2,
            title: "Spiderman"
        }
    ]
};

export const MovieContext = createContext(initialState);

export const MovieProvider = (props: { children: React.ReactNode }) => {
    const [state, dispatch] = useReducer(MovieReducer, initialState);

    // Actions
    function deleteMovie(id: number): void {
        dispatch({
            type: 'DELETE_MOVIE',
            payload: { id, title: 'nil' }
        })
    }

    function addMovie(id: number, title: string): void {
        dispatch({
            type: 'ADD_MOVIE',
            payload: { id, title }
        })
    }

    return (
        <MovieContext.Provider value={{
            movies: state.movies,
            deleteMovie,
            addMovie
        }}>
            {props.children}
        </MovieContext.Provider>
    )
}

如果代码的任何部分也可以改进,请告诉我!我最近才开始研究 Typescript,今天才开始研究 Context。

上下文的类型取决于它的声明。如果在上面的树中没有上下文提供者的情况下检索上下文,则在调用 createContext 时需要指定类型以及合理的默认值:

// You could move the anonymous type between <> to an interface 
export const MovieContext = createContext<{
  movies: Movie[],
  deleteMovie(id: number): void;
  addMovie(id: number, title: string): void;
}>({
  ...initialState,
  addMovie: () => {},
  deleteMovie: () => {}
});

Playground Link