在 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) => 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 的调度中使用未声明的字段时如何获取打字稿错误的主要内容,如果未能解决你的问题,请参考以下文章
使用 LINQ to SQL 时如何处理 SqlException“未找到记录”?