typescript - typeof variable === "function" 为真,但由于意外的类型合并,变量仍然缺少调用签名
问题描述
非常类似于 React 我想在自定义库中使用状态,我目前有以下类:
export abstract class Room<State> {
protected state: State;
protected setState<Key extends keyof State>(
state: ((previousState: Readonly<State>) => Pick<State, Key> | State)
| (Pick<State, Key> | State)
) {
if (typeof state === "function") {
// Cannot invoke an expression whose type lacks a call signature. Type
// '((previousState: Readonly<State>) => State | Pick<State, Key>) | (State & Function)'
// has no compatible call signatures.
const newState = state(this.state);
// ...
}
// ...
}
// ...
}
正如您在评论中看到的那样,Typescript 抱怨 state 缺少调用签名,尽管我希望能够区分 state 参数的两种类型。令人惊讶的是,在它工作| State
的类型末尾删除 final 时state
,VS Code 中的 Intellisense 不再提供诸如this.setState({ foo: 1 });
.
为什么 Typescript 会合并第二种类型的state
to State & Function
?是否可以安全地重写它?
解决方案
希望这会有所帮助,首先这里发生了一些事情,额外的括号什么都不做,因为联合是可交换的意思 A | (B | C) 与 (A | B) | 相同 C 基本上括号没有任何意义,其次要解决函数问题,只需编写 typeof state !== "object" 意味着你从联合中摆脱了 2/3,只剩下函数。希望这可以帮助
export abstract class Room<State extends object> {
protected state: State = "" as any;
protected setState<Key extends keyof State>(
state: ((previousState: Readonly<State>) => Pick<State, Key> | State) | (Pick<State, Key>) | State
) {
if (typeof state !== "object") {
const newState = state(this.state);
}
}
}
抱歉编辑,它失败的原因是因为当打字稿一般解释它时,对 State 含义没有通用约束,它不能假设 State 不是函数,这意味着 typeof state === "function" 可能会给你留下任何类型状态是。
推荐阅读
- nginx - 如何使用 NGINX 正确设置多个站点?
- sql - 选择命令中的聚合函数与非聚合函数
- java - 如何修复 Layoutinflator not found 错误?
- powershell - 使用 PowerShell 执行调用批处理文件的远程脚本
- powershell - 通过 REST API 创建服务连接时无法加载私钥
- javascript - 如何在没有日志记录的情况下清除浏览器控制台?
- python - FactoryBoy - 嵌套工厂/最大深度?
- c++ - 如何在 C++ 中宏#define 静态方法调用?
- javascript - 尝试签署 jwt 会返回 undefined
- google-sheets - 对字符串中的数字求和 Google 表格