PrevState 在 TypeScript 中输入

Laz*_*zyk 7 typescript reactjs

我正在使用上下文来存储对话框的对象。我有一个函数可以根据 prevState 更新存储在上下文中的数组,但是 TypeScript 不喜欢我的 prevState 类型。

类型“(prevState: SourceOrganizationAccount[]) => SourceOrganizationAccount[]”的参数不可分配给“SourceOrganizationAccount[]”类型的参数。类型“(prevState: SourceOrganizationAccount[]) => SourceOrganizationAccount[]”缺少类型“SourceOrganizationAccount[]”中的以下属性:pop、push、concat、join 以及其他 27 个属性。

这是我的带有 function 的组件handleCheckAccountDetailsClick。它在这条线上抱怨sourceOrganizationAccounts.setValue((prevState: SourceOrganizationAccount[]) => {。prevState 有什么问题吗?

import React from 'react';
import { getAccount } from 'utils';
import {
  SourceOrganizationAccount,
  useImportAccountsContext,
} from '../ImportAccountsContext';

export function ImportAccountsTable() {
  const { sourceOrganizationAccounts } = useImportAccountsContext();

  async function handleCheckAccountDetailsClick(account: SourceOrganizationAccount) {
    const accountDetailsRes = await getAccount();

    if (accountDetailsRes.success) {
      sourceOrganizationAccounts.setValue((prevState: SourceOrganizationAccount[]) => {
        const updatedArray = prevState.map(sourceOrganizationAccount => {
          return sourceOrganizationAccount.locator === account.locator
            ? {
                ...sourceOrganizationAccount,
                ...accountDetailsRes.accountDetails,
              }
            : sourceOrganizationAccount;
        });

        return updatedArray;
      });
    }
  }

  return <>Test</>;
}
Run Code Online (Sandbox Code Playgroud)

我的类型

export type SourceOrganizationAccount = {
  name: string;
  createdOn: number;
  locator: string;
}

export interface StateVariable<T> {
  value: T;
  setValue: (value: T) => void;
}

export interface ImportAccountsState {
    sourceOrganizationAccounts: StateVariable<SourceOrganizationAccount[]>;
}

const ImportAccountsContext = createContext<ImportAccountsState>(
  {} as ImportAccountsState,
);

export const ImportAccountsProvider = ({ children }: props) => {
  const [sourceOrganizationAccounts, setSourceOrganizationAccounts] = useState<
    SourceOrganizationAccount[]
  >([]);

  const resetContext = useCallback(() => {
    setSourceOrganizationAccounts([]);
  }, [
    setSourceOrganizationAccounts,
  ]);

  const initialState: ImportAccountsState = {
    sourceOrganizationAccounts: {
      value: sourceOrganizationAccounts,
      setValue: setSourceOrganizationAccounts,
    }
  };

  return (
    <ImportAccountsContext.Provider value={initialState}>
      {children}
    </ImportAccountsContext.Provider>
  );
};

export const useImportAccountsContext = () => {
  return useContext<ImportAccountsState>(ImportAccountsContext);
};
Run Code Online (Sandbox Code Playgroud)

ale*_*xor 11

如果您彻底检查您的StateVariable<T>类型,您可能会注意到setValue该类型的字段具有签名:

setValue: (value: T) => void
Run Code Online (Sandbox Code Playgroud)

当您尝试向它提供类型的值T(而不是类型的值)时:(prevState: T) => T

为了匹配您的函数实现,类型StateVariable应定义为:

interface StateVariable<T> {
  value: T;
  setValue: (cb: (value: T) => T) => void;
}
Run Code Online (Sandbox Code Playgroud)

React 公开了用于键入useState调度函数的特殊帮助器类型:Dispatch<SetStateAction<T>>因此您也可以将其编写为:

import { Dispatch, SetStateAction } from 'react'

interface StateVariable<T> {
  value: T
  setValue: Dispatch<SetStateAction<T>>
}
Run Code Online (Sandbox Code Playgroud)

  • 这就是解决方案,如果反应说:```类型'(count:number)=&gt; number'的参数不能分配给类型'number'的参数。```和```您是要调用这个表达式吗? ``` 使用先前值回调设置状态时。 (2认同)