typescript - 当类型定义中使用泛型和条件时,Typescript 不会在 switch 语句中推断类型
问题描述
我有一个函数的类型定义。我将第二个参数的类型定义为以第一个参数的类型为条件,如下所示:
const FOO = "FOO";
const BAR = "BAR";
let fooPayload = {
zip: "zap"
}
let barPayload = {
cat: "dog"
}
type ActionTypes = typeof FOO | typeof BAR;
interface MyFunction<T extends ActionTypes = ActionTypes> {
(
action: {
type: T;
payload: T extends typeof FOO
? typeof fooPayload
: typeof barPayload;
}
): boolean;
}
接口引用的函数在其中MyFunction
有一个 switch 语句,它基于切换,action.type
并且根据情况,对action.payload
. 这是一个例子:
const myFunction:MyFunction = (action) => {
switch (action.type) {
case FOO:
action.payload.zip = "new zap"
return true
case BAR:
action.payload.cat = "new dog"
return false
default:
return false
}
}
我遇到的问题是 Typescript 没有正确推断出action.payload
switch 语句应该是什么。例如,如果action.type
等于“FOO”,那么它应该推断出action.payload
必须是typeof fooPayload
。相反,它推断它是typeof fooPayload | typeof barPayload
.
这没有任何意义,因为 for 的类型定义action.payload
基于 的值action.type
,并且由于在仅当等于 "FOO"action.payload.zip
时才会出现的 switch 语句中被调用,因此它应该推断 for 唯一可能的类型是。action.type
action.payload
typeof fooPayload
我在这里做错了什么?
解决方案
我不确定这会导致问题的确切位置,但总的来说,问题是您正在尝试重新发明打字稿已经做得很好的东西,狭窄的类型联合。
条件是一个非常有趣的特性,但有时会表现得有点出乎意料,因为它们是分布式的,因为它们超出了定义的范围。
我会以不同的方式实现它:
interface Action<T, P> {
type: T,
payload: P
}
type Actions
= Action<typeof FOO, typeof FooPayload>
| Action<typeof BAR, typeof BarPayload>
;
interface MyFunction {
(action: Actions): boolean;
}
不需要条件,打字稿将按预期在切换中缩小联合。
推荐阅读
- java - Mokito:Java 中的匹配函数
- python - 如何使用 QPushButton(Python) 停止线程?
- reactjs - req.params 未在 Axios 发布请求上从 React 前端传递到无服务器函数
- spring - Dockerfile 无法使用 Maven 构建应用程序 - 没有为此构建指定目标
- ffmpeg - Ffmpeg-fluent 抛出“必须指定至少一个输出文件”错误
- c# - 使用 IComparable 根据参数对对象的 ArrayList 进行排序
- javascript - 将 alpaca 导入 React.js
- python - 如何从子处理的python脚本打印到终端窗口
- arrays - 在映射时将项目添加到`useState`变量`array`会导致React本机函数组件中出现过多的重新渲染错误
- ruby-on-rails - 卸载新的默认版本的 Ruby gems - 无法安装基于 gemspec 文件的依赖库