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:使用泛型的递归深度可变。错误:T不可分配给可变<;T>;_Typescript_Generics_Mutable_Typescript3.0 - Fatal编程技术网

TypeScript:使用泛型的递归深度可变。错误:T不可分配给可变<;T>;

TypeScript:使用泛型的递归深度可变。错误:T不可分配给可变<;T>;,typescript,generics,mutable,typescript3.0,Typescript,Generics,Mutable,Typescript3.0,我正在尝试编写一个深度递归可变类型: Mutable<T> = ... // remove all "readonly" modifiers // convert all ReadonlyArray to Array // etc. // and do it all recursively const mutate = <T>(val: T, mutateFn: (mutableVal: Mutable<T>) => v

我正在尝试编写一个深度递归
可变
类型:

Mutable<T> = ...
    // remove all "readonly" modifiers
    // convert all ReadonlyArray to Array
    // etc.
    // and do it all recursively

const mutate = <T>(val: T, mutateFn: (mutableVal: Mutable<T>) => void): T => {
  return null as any
}
Mutable=。。。
//删除所有“只读”修改器
//将所有只读数组转换为数组
//等等。
//然后递归地完成这一切
常量mutate=(val:T,mutateFn:(mutableVal:Mutable)=>void:T=>{
返回null作为任意值
}
只要我不使用泛型,它就可以正常工作:

// works fine
mutate([] as ReadonlyArray<string>, mutableVal => {
  mutableVal.splice(42, 0, "test");
});
//很好用
变异([]为只读数组,可变值=>{
可变值拼接(42,0,“测试”);
});
但在泛型函数中使用它时,我会得到一个错误:

// Error: Argument of type 'T' is not assignable to parameter of type 'Mutable<T>'.
const doSomething = <T>(array: ReadonlyArray<T>, index: number, elem: T) => {
  mutate(array, mutableVal => {
                      // Here's the error
                      //         v
    mutableVal.splice(index, 0, elem);
  });
}
//错误:“T”类型的参数不可分配给“Mutable”类型的参数。
常量doSomething=(数组:ReadonlyArray,索引:number,元素:T)=>{
mutate(数组,mutableVal=>{
//这是错误
//五
可变值拼接(索引,0,元素);
});
}
我知道可变数组的类型是
array
,而
splice
现在需要的是
mutable
值,而不是
T
。但我不知道怎么解决它

你知道怎么解决这个问题吗

我已经创建了一个TypeScript游戏场,因此您可以使用以下代码:
我的建议是这样做:

const doSomething = <T>(array: ReadonlyArray<T>, index: number, elem: T) => {
    mutate({ array: array, elem: elem }, mutableVal => {
        mutableVal.array.splice(index, 0, mutableVal.elem);
    });
}
const doSomething=(数组:ReadonlyArray,索引:number,元素:T)=>{
mutate({array:array,elem:elem},mutableVal=>{
mutableVal.array.splice(索引,0,mutableVal.elem);
});
}
这个想法是,您需要
elem
是可变的,以便将其添加到深度可变数组中,但您最初的调用并没有这样做。由于您希望同时变异
数组
元素
,因此最简单的解决方案是传入一个同时包含
数组
元素
的对象,并对该对象的深层可变版本进行操作

只有您知道在
elem
array
上调用
mutate()
是否可以接受,因为
mutate()
的实现被省略了。我猜这会涉及到这样的断言:

const doSomething = <T>(array: ReadonlyArray<T>, index: number, elem: T) => {
    mutate({ array: array, elem: elem }, mutableVal => {
        mutableVal.array.splice(index, 0, mutableVal.elem);
    });
}
constmutate=(val:T,mutateFn:(mutableVal:Mutable)=>void:T=>{

mutateFn(val为可变值)/
T
Mutable
显然不兼容,但您想如何处理这一点?简单的选择是将
elem
键入为
Mutable
。另一个选择是不在数组上执行深度Mutable…这在很大程度上取决于您的用例,您想做什么我不确定如何处理,这就是为什么我要创建此问题。
T
Mutable
应始终具有相同的结构:
{readonly foo:string}
变为
{foo:string}
。并且
只读数组
变成
数组
。用例就像我发布的代码中的
mutate
函数。但是在某些情况下,我想在另一个函数中使用
mutate
函数(比如
doSomething
)然后它就不起作用了。当然我可以把
元素写成可变的
,它工作得很好。但我希望能找到一个现成的解决方案。这也是一个可能的解决方案。谢谢。基本上
mutate
函数应该是一个对象(或数组)可变。
elem
不需要是可变的,如果你只想改变数组。如果你想改变
elem
,你可以调用
mutate(elem,…)
。或者如果你想改变两者,你可以为两者调用
mutate
(,或者在你的代码中:创建一个新对象,两者都在里面)。有很多解决方案(,你甚至可以像任何地方的任何人一样使用
)。我只是认为可能会保持简单,让TypeScript在幕后完成它的工作。“如果你只想改变数组,那么
元素不必是可变的。”但是你不能将一个不可变元素添加到一个深度可变数组中,对吗?这就是为什么它是“深度”的原因。如果您只想对数组进行变异,而不要求其内容也是可变的,那么您只需要一个普通的
数组
,而不是
数组
,这就是
可变的
的形式。在我听来,您确实想要一些不一致的东西。您的选择是制作一个简单可变的
数组
(这意味着你不能调用
mutate()
,正如上面在
array
上定义的那样),制作一个可变版本的
elem
(这意味着你需要在
array
elem
上调用
mutate()
),或者你只需要通过调用
mutate()来声明你的出路
仅在
array
上传递
elem作为可变的
而不是
elem
。但是在最后一种情况下,您必须故意使(有效的)编译器消息静音,警告您正在尝试执行不安全的操作。是的,这是真的。我还没有考虑过这种情况。。。“如果您将一个不可变的
元素
添加到可变的
数组
中,然后尝试对该元素进行变异,会怎么样?“我的第一个想法是:即使在将
元素添加到数组中后,也禁止对其进行变异。但是之前数组中的所有内容都应该是可变的。也许我需要再睡一晚:D无论如何:谢谢你的提示!