在 TypeScript 中解构 React hooks 数组时,该表达式不可调用

Afs*_*5mm 4 javascript typescript reactjs react-hooks

在我的 React TS 组件中,我有一堆字段(下面是人为的示例),它们检查特定条件,如果不满足,则将特定字段错误设置为 true,以反映和组件 DOM(因此不提交)但是,当我有下面的代码时,它会在函数expression not callable上抛出一个错误setErr

const App = () => {
  const [name, setName] = React.useState("");
  const [email, setEmail] = React.useState("");
  const [nameError, setNameError] = React.useState(false);
  const [emailError, setEmailError] = React.useState(false);
  return (
    <div className="App">
      <input
        type="text"
        value={name}
        style={{
          border: `1 px solid ${nameError ? "red" : "black"}`
        }}
        onChange={e => {
          setName(e.target.value);
        }}
      />
      <input
        type="text"
        value={email}
        onChange={e => {
          setEmail(e.target.value);
        }}
        style={{
          border: `1 px solid ${emailError ? "red" : "black"}`
        }}
      />
      <button
        onClick={() => {
          const errors = [
            [setNameError, name.length],
            [setEmailError, email.length]
          ];

          let canSubmit = true;
          errors.forEach(validation => {
            const [setErr, condition] = validation;
            console.log(!condition);
            if (!condition) {
              canSubmit = false;
              setErr(true); // <---- ERROR HERE
            }
          });

          if (canSubmit) { /* submit the form */ } 
        }}
      >
        submit
      </button>
    </div>
  );
};
Run Code Online (Sandbox Code Playgroud)

这仅在 TypeScript 中出现错误,因为它在 vanilla/jsx 中工作正常。并且在某些构建系统中无法编译。

完整错误是:

This expression is not callable.
  Not all constituents of type 'string | number | boolean | Dispatch<SetStateAction<boolean>>' are callable.
    Type 'string' has no call signatures.
Run Code Online (Sandbox Code Playgroud)

我特别困惑为什么它认为setErr是字符串类型,而它应该等于从 useState 解构的 setNameError 函数。

Jon*_*lms 9

您所需要做的就是添加as const到声明中errors

  const errors = [
        [setNameError, name.length],
        [setEmailError, email.length]
   ] as const;
Run Code Online (Sandbox Code Playgroud)

这样,数组就不会被键入为数组,而是被键入为元组。