在 useState 的调度中使用未声明的字段时如何获取打字稿错误

Posted

技术标签:

【中文标题】在 useState 的调度中使用未声明的字段时如何获取打字稿错误【英文标题】:How to get typescript error when using undeclared fields in useState's dispatch 【发布时间】:2021-07-04 20:30:16 【问题描述】:

理想情况下,我想知道为什么 ts 在下面的情况下不会抛出任何错误,以及是否有办法解决它以使其按预期工作。

尝试通过useState 的调度程序回调更新某些状态时,我预计会出现打字稿错误,但没有任何反应。这似乎是有效的:

  type State = 
    age?: number;
  ;

  const [, setState] = useState<State>();

  setState((prev) => 
    // const copy =  ...prev ;
    // this is a ts error;
    // copy.name = "scotty";
    // this is not
    return  ...prev, name: "scotty" ;
  );

我希望 ts 在额外的未声明字段 name 上引发错误(我可以指定返回类型,但我不应该这样做,因为应该推断调度的参数 ((prevState: S) =&gt; S))。

我怎样才能输入这样我得到我期待的 ts 错误;此更新唯一允许的字段应该是在State 中定义/类型的字段。

最重要的是为什么这不起作用?

这里有一个codesandbox 来玩。

【问题讨论】:

一般来说,Typescript 不认为额外的属性是一个问题。如果一个对象适合age?: number,那么它就是State 【参考方案1】:

Typescript 错误来自 typescript linter,它由您通常放在项目根目录的 tsconfig.json 文件定义。

并且您没有在您的codesandbox 中添加任何tsconfig.json

请将此 tsconfig.json 添加到您的根文件夹中,以获得您预期的 lint 错误:



  "compilerOptions": 
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  ,
  "include": [
    "src"
  ]


将此添加到您的代码框后,我得到了预期的错误:

现在您可以在此错误中看到,它仍然允许您在不应添加的位置添加 name 属性。

为此,您只需将返回类型添加到您的 SetStateAction :


  useEffect(() => 
    
    setState((prev):State =>  // <=== Add the State return type here
      // const copy =  ...prev ;
      // copy.name = "scotty";
      return  ...prev, name: "scotty" ;
    );
  , []);

单线解决方案:

  useEffect(() => setState((prev) => ( ...prev, age: 9 )), []);

【讨论】:

嘿,我用我的 tsconfig 更新了代码框。这并不能解决我的问题/解释为什么 ts 在我期望的地方也没有抛出错误。在您的示例中,该错误是预期的,因为年龄不是可选类型并且未提供。我希望它在额外字段 name 上出错,因为它没有定义为 State 类型。 还更新了代码 sn-ps 以通过将age 设为可选来突出显示这一点。

以上是关于在 useState 的调度中使用未声明的字段时如何获取打字稿错误的主要内容,如果未能解决你的问题,请参考以下文章

使用 GHCi 时如何为函数提供显式类型声明?

在Angular中使用Input传递数据时如何处理未定义?

使用 LINQ to SQL 时如何处理 SqlException“未找到记录”?

UILocalNotification - 应用程序未运行时如何处理?

使用useState(Reactjs)时未选中材料表复选框

应用未运行时如何处理远程通知