typescript 使用上下文时,类型“...”不能分配给类型“...”

amrnrhlw  于 2023-06-07  发布在  TypeScript
关注(0)|答案(2)|浏览(401)

我在Next.js中使用createContext来创建一个暗模式按钮;这里是ThemeContext.tsx,它最初是一个普通的jsx文件;我正在尝试将其转换为TypeScript。

"use client";

import { useState, createContext } from "react";

type ThemeContextType = "light" | "dark";

interface ChildrenProps {
  children: React.ReactNode;
}

export const ThemeContext = createContext<ThemeContextType>("light");

export const ThemeProvider = ({ children }: ChildrenProps) => {
  const [mode, setMode] = useState<string>("dark");

  const toggle = (): void => {
    setMode((prev) => (prev === "dark" ? "light" : "dark"));
  };
  return (
    <ThemeContext.Provider value={{ toggle, mode }}>
      <div className={`theme ${mode}`}>{children}</div>
    </ThemeContext.Provider>
  );
};

我从ThemeContext.Provider value={{toggle, mode}}>中的value得到错误

Type '{ toggle: () => void; mode: string; }' is not assignable to type 'ThemeContextType'.ts(2322)

index.d.ts(329, 9): The expected type comes from property 'value' which is declared here on type 'IntrinsicAttributes & ProviderProps<ThemeContextType>'
8wtpewkr

8wtpewkr1#

您看到的错误是因为您提供给ThemeContext.Provider的值与预期的ThemeContextType类型不匹配。Provider的值属性需要一个ThemeContextType类型的值,该类型定义为“light”|“dark”。但是,您传递的对象具有属性toggle和mode,这与预期的类型不匹配。
要解决这个问题,可以为上下文值创建一个单独的接口,并将其用作ThemeContext.Provider值的类型。下面是代码的更新版本:

import { useState, createContext } from "react";

type ThemeContextType = "light" | "dark";

interface ThemeContextValue {
  toggle: () => void;
  mode: ThemeContextType;
}

interface ChildrenProps {
  children: React.ReactNode;
}

export const ThemeContext = createContext<ThemeContextValue>({
  toggle: () => {},
  mode: "light",
});

export const ThemeProvider = ({ children }: ChildrenProps) => {
  const [mode, setMode] = useState<ThemeContextType>("dark");

  const toggle = (): void => {
    setMode((prev) => (prev === "dark" ? "light" : "dark"));
  };

  const contextValue: ThemeContextValue = {
    toggle,
    mode,
  };

  return (
    <ThemeContext.Provider value={contextValue}>
      <div className={`theme ${mode}`}>{children}</div>
    </ThemeContext.Provider>
  );
};

在这段更新的代码中,我们定义了ThemeContextValue接口来表示上下文值的结构。我们提供了toggle和mode属性的默认值,以防未提供它们。然后,我们将contextValue变量的类型显式设置为ThemeContextValue,并将其作为ThemeContext.Provider的值传递。
通过这些更改,错误应该得到解决,并且您应该能够在Next.js应用中使用ThemeProvider和ThemeContext而不会出现任何问题。

b4wnujal

b4wnujal2#

您需要更新ThemeContextType,因为到目前为止,它使提供程序的value只能接受等于“light”或“dark”的字符串。这应该可以工作:

"use client";

import { useState, createContext } from "react";

type ModeType = "light" | "dark";
type ThemeContextType = {
  mode: ModeType;
  toggle: () => void;
};

interface ChildrenProps {
  children: React.ReactNode;
}

export const ThemeContext = createContext<ThemeContextType>({ mode: "light", toggle: () => {} });

export const ThemeProvider = ({ children }: ChildrenProps) => {
  const [mode, setMode] = useState<ModeType>("dark");

  const toggle = (): void => {
    setMode((prev) => (prev === "dark" ? "light" : "dark"));
  };

  return (
    <ThemeContext.Provider value={{ toggle, mode }}>
      <div className={`theme ${mode}`}>{children}</div>
    </ThemeContext.Provider>
  );
};

相关问题