Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 类型安全的深度更新:可以用不相关的任意类型实例化_Typescript - Fatal编程技术网

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)
    }