Typescript 类型安全的深度更新:可以用不相关的任意类型实例化
在Typescript 类型安全的深度更新:可以用不相关的任意类型实例化,typescript,Typescript,在update\u substate功能中,是否有任何方法可以将作为任何删除?直接调用update_state函数时是类型安全的,所以间接调用也应该是安全的?这些是Redux状态的轻量级辅助函数。我已经阅读了一些相关问题(,),但还不了解解决方案 export function update_state < RootState, P1 extends keyof RootState, S1 extends RootState[P1], > (root_stat
update\u substate
功能中,是否有任何方法可以将作为任何
删除?直接调用update_state函数时是类型安全的,所以间接调用也应该是安全的?这些是Redux状态的轻量级辅助函数。我已经阅读了一些相关问题(,),但还不了解解决方案
export function update_state <
RootState,
P1 extends keyof RootState,
S1 extends RootState[P1],
> (root_state: RootState, path1: P1, replacement_state: S1)
{
const current = root_state[path1]
if (current === replacement_state) return root_state
return {
...root_state,
[path1]: replacement_state
}
}
export function update_substate <
RootState,
P1 extends keyof RootState,
S1 extends RootState[P1],
P2 extends keyof S1,
S2 extends S1[P2],
> (root_state: RootState, path1: P1, path2: P2, replacement_substate: S2)
{
/**
Without the `as any` will get the error:
Argument of type 'RootState[P1]' is not assignable to parameter of type 'S1'.
'S1' could be instantiated with an arbitrary type which could be unrelated to 'RootState[P1]'.
Type 'RootState[keyof RootState]' is not assignable to type 'S1'.
'S1' could be instantiated with an arbitrary type which could be unrelated to 'RootState[keyof RootState]'.
Type 'RootState[string] | RootState[number] | RootState[symbol]' is not assignable to type 'S1'.
'S1' could be instantiated with an arbitrary type which could be unrelated to 'RootState[string] | RootState[number] | RootState[symbol]'.
Type 'RootState[string]' is not assignable to type 'S1'.
'S1' could be instantiated with an arbitrary type which could be unrelated to 'RootState[string]'.ts(2345)
*/
const replacement_state = update_state<S1, P2, S2>(root_state[path1] as any, path2, replacement_substate)
return update_state(root_state, path1, replacement_state)
}
导出功能更新\u状态<
根州,
P1扩展了根状态的键,
S1扩展根状态[P1],
>(根状态:根状态,路径1:P1,替换状态:S1)
{
const current=root_状态[path1]
如果(当前===替换_状态)返回根_状态
返回{
…根州,
[路径1]:替换状态
}
}
导出函数更新子状态<
根州,
P1扩展了根状态的键,
S1扩展根状态[P1],
P2扩展了S1的键,
S2扩展S1[P2],
>(根状态:根状态,路径1:P1,路径2:P2,替换子状态:S2)
{
/**
如果没有'as any',则会出现错误:
“RootState[P1]”类型的参数不能分配给“S1”类型的参数。
“S1”可以用与“RootState[P1]”无关的任意类型实例化。
类型“RootState[keyof RootState]”不可分配给类型“S1”。
“S1”可以用与“RootState[keyof RootState]”无关的任意类型实例化。
类型“RootState[string]| RootState[number]| RootState[symbol]”不可分配给类型“S1”。
“S1”可以用与“RootState[string]| RootState[number]| RootState[symbol]”无关的任意类型实例化。
类型“RootState[string]”不可分配给类型“S1”。
“S1”可以用与“RootState[string]”无关的任意类型实例化。ts(2345)
*/
const replacement_state=更新_state(根_state[path1]如有,路径2,replacement_substate)
返回更新状态(根状态、路径1、替换状态)
}
以下是一种编译代码段的方法(无需检查其内容):
S1
,因为它不在update\u substate
函数签名中使用update\u state
声明它们P2
的泛型约束更新为P2/RootState[P1]
导出函数更新\u子状态<
根州,
P1扩展了根状态的键,
P2扩展根状态[P1]的键,
S2扩展根状态[P1][P2],
>(根状态:根状态,路径1:P1,路径2:P2,替换子状态:S2)
{
const replacement_state=更新_state(根_state[path1],path2,replacement_substate)
返回更新状态(根状态、路径1、替换状态)
}
非常感谢您快速给出答案和解决方案。它工作得很好。是的,我认为“省略类型参数xyz,因为它不用于函数签名”是一个很好的测试。
export function update_substate <
RootState,
P1 extends keyof RootState,
P2 extends keyof RootState[P1],
S2 extends RootState[P1][P2],
> (root_state: RootState, path1: P1, path2: P2, replacement_substate: S2)
{
const replacement_state = update_state(root_state[path1], path2, replacement_substate)
return update_state(root_state, path1, replacement_state)
}