【问题标题】:This expression is not callable when destructuring an array of React hooks in TypeScript在 TypeScript 中解构 React 钩子数组时,此表达式不可调用
【发布时间】:2020-04-09 23:46:34
【问题描述】:

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

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>
  );
};

这只会在 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.

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

【问题讨论】:

  • error 的推断类型是什么?
  • errorserror? @JonasWilms
  • 我建议使用null 作为“无价值”的占位符,而不是false,这是对是/否问题的回答

标签: javascript reactjs typescript react-hooks


【解决方案1】:

您只需将as const 添加到errors 声明中:

  const errors = [
        [setNameError, name.length],
        [setEmailError, email.length]
   ] as const;

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

【讨论】:

    【解决方案2】:

    errors 的推断类型是让您失望的原因。根据您的错误消息,我们可以得出const errors: (string | number | boolean | Dispatch&lt;SetStateAction&lt;boolean&gt;&gt;)[][],因此打字稿推断数组元素可以是一堆东西,其中一些是不可调用的。相反,您可以将其对象化,并将推断的类型分配给键,从而允许您进行解构和正确调用,即

    <button
      onClick={() => {
        const errors = [
          {setError:setNameError, condition:name.length},
          {setError:setEmailError, condition:email.length}
        ];
    
        let canSubmit = true;
        errors.forEach(validation => {
          const {setError, condition} = validation;
          console.log(!condition);
          if (!condition) {
            canSubmit = false;
            setError(true); // <---- ERROR HERE
          }
        });
    
        if (canSubmit) { /* submit the form */ } 
      }}
    >
    

    【讨论】:

      猜你喜欢
      • 2020-08-16
      • 2021-06-12
      • 2021-05-05
      • 2021-04-27
      • 2021-02-12
      • 2020-07-31
      • 2021-05-17
      • 2022-12-05
      • 2020-11-21
      相关资源
      最近更新 更多