typescript - 打字稿:给定一个函数表,创建一个函数,该函数接受表的键和表中函数的第二个参数
问题描述
尝试为状态编写一个简单的存储。
我有一个基本状态:
const state = {
health: 100,
maxHealth: 100,
};
type State = typeof state;
我有一组突变
const mutations = {
setHealth: (state: State, payload: { newHealth: number }) => {
state.health = payload.newHealth;
},
setMaxHealth: (state: State, payload: { newMaxHealth: number }) => {
state.maxHealth = payload.newMaxHealth;
},
} as const;
type Mutations = typeof mutations;
我想要做的是创建一个函数,它可以将突变的键作为它的第一个参数,并将突变的有效负载作为它的第二个参数。
我目前有,第一个参数输入正确,但第二个参数mutations[mutation]
错误type Parameters<Mutations[M]>[1] is not assignable to parameter of type '{ newHealth: number; } & { newMaxHealth: number; }'.
const commit = <M extends keyof Mutations>(mutation: M, payload: Parameters<Mutations[M]>[1]) => {
mutations[mutation](state, payload);
};
解决方案
问题是当 TS 想要它时,mutations[mutation]
评估(state: State, payload: { newHealth: number } & { newMaxHealth: number }) => void
和你的payload
变量评估{ newHealth: number; } | { newMaxHealth: number; }
{ newHealth: number; } & { newMaxHealth: number; }
这是有道理的,因为 TS 想要mutations[mutation]
一次将所有可能的函数视为所有可能的函数。从 TS 的角度来看,为了作为(setHealth | setMaxHealth)payload
的参数有效,它必须同时匹配所有可能的函数定义。mutations[mutation]
我处理这个问题的方法是断言mutations[mutation]
匹配我们的payload
类型:
interface State {
health: number;
maxHealth: number;
}
const mutations = {
setHealth: (state: State, { newHealth }: { newHealth: number }) => {
state.health = newHealth;
},
setMaxHealth: (state: State, { newMaxHealth }: { newMaxHealth: number }) => {
state.maxHealth = newMaxHealth;
},
};
type Mutations = typeof mutations;
const o = {
state: { health: 0, maxHealth: 0 },
commit<M extends keyof Mutations, P extends Parameters<Mutations[M]>[1]>(mutation: M, payload: P) {
(mutations[mutation] as (state: State, payload: P) => void)(this.state, payload);
},
};
o.commit("setHealth", { newHealth: 50 });
o.commit("setMaxHealth", { newMaxHealth: 100 });
(旁注:P
对有效负载类型使用泛型意味着具有额外成员的对象将被视为有效,例如o.commit("setMaxHealth", { newMaxHealth: 100, x: 1 })
不会出错。如果您不想要此功能,只需在每个地方替换P
)Parameters<Mutations[M]>[1]
祝你好运!
推荐阅读
- javascript - 无法链接 useEffects 以使用来自先前效果的更新状态
- tensorflow - COCO json 注解转 YOLO txt 格式
- git - 从 Github 存储库获取最新数据 - Github 桌面
- sql - 在 pyspark 中查找过去 n 天内出现的 id
- java - Spring Boot 2 获取客户端时区
- c - 使用 OpenSSL 的非顺序 AES-CTR
- transparency - c# WinForms中的透明FlowLayoutPanel
- google-apps-script - 在 Google AppScript 中使用 Web3?
- postgresql - Spring Boot App 无法使用来自 Kubernetes 机密的凭据访问 PostgreSQL
- r - 文本挖掘时单词被截断