Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.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,我有一个类型a,有几个属性,可以是不同的键:字符串、数字、类型B、无关。我想在某些字段上从类型为A的对象a1复制到类型为A的对象a2,但我事先不知道要复制哪些字段。我要复制的字段包含在一个字符串文本数组中,它告诉我要复制哪个字段 type A = { name: string, length: number, thing: B } const a1: A = { name: "test", length: 2, thing: { whatever

我有一个类型a,有几个属性,可以是不同的键:字符串、数字、类型B、无关。我想在某些字段上从类型为A的对象a1复制到类型为A的对象a2,但我事先不知道要复制哪些字段。我要复制的字段包含在一个字符串文本数组中,它告诉我要复制哪个字段

type A = {
    name: string,
    length: number,
    thing: B
}

const a1: A = {
    name: "test",
    length: 2,
    thing: { whatever: true },
}

const a2: A = {
    name: "",
    length: 0,
    thing: {whatever: false}
}

const propNames = ["name", "length"]

propNames.map(propName => a2[propName] = a1[propName as keyof A])
如果有任何可能的帮助,我将不胜感激,以下是沙盒上的示例:

  • 确定包含要复制的所有键/值的对象
  • 从空对象开始,对要复制的每个属性使用
    reduce
  • 将目标对象与要覆盖的值组合
    函数copyPropertiesOver(属性:string[],源:E,目标:E):E{
    常数值stobecopied=arr.reduce(
    (acc,curr)=>({…acc,curr:source[curr as keyof E]}),
    {}
    );
    const targetUpdated=({…target,…valuesToBeCopied}未知)作为E;
    返回目标更新;
    }
    const a2Updated=copyPropertiesOver

  • 确定包含要复制的所有键/值的对象
  • 从空对象开始,对要复制的每个属性使用
    reduce
  • 将目标对象与要覆盖的值组合
    函数copyPropertiesOver(属性:string[],源:E,目标:E):E{
    常数值stobecopied=arr.reduce(
    (acc,curr)=>({…acc,curr:source[curr as keyof E]}),
    {}
    );
    const targetUpdated=({…target,…valuesToBeCopied}未知)作为E;
    返回目标更新;
    }
    
    const a2Updated=copyPropertiesOver

    如果编写
    const arr=[“some”,“strings”]
    编译器将推断
    arr
    属于
    string[]
    类型,它将立即忘记其内容的确切数字和值。这通常是正确的行为,因为人们确实倾向于改变数组的内容(即使是
    const
    的数组也可以有
    arr[0]=“赋值”
    arr.push(“push”);

    如果希望编译器跟踪数组文字中的特定内容,则需要更改声明变量的方式。最简单的方法是在TypeScript 3.4中介绍的:

    const arr = ["name", "length"] as const;
    
    现在已知
    arr
    的类型是一个长度为2的数组,其第一个元素必须是
    “name”
    ,第二个元素必须是
    “length”
    。因此,如果您编写
    arr.map(propName=>…)
    ,编译器将知道
    propName
    必须是
    “name”|“length”


    如果你解决了这个问题,你将面临的第二个问题是:

    这里的问题是编译器认为赋值可能不安全,因为它无法验证
    a2[propName]
    设置的属性与您从
    a1[propName]
    读取的属性完全相同。这对我们来说很明显,因为变量
    propName
    是相同的,但编译器看到的是这些访问使用相同的键类型,这是两种可能的联合,有四种可能的结果,如下所示:

    const propName2 = arr[Math.random() < 0.5 ? 0 : 1];
    const propName1 = arr[Math.random() < 0.5 ? 0 : 1];
    a2[propName2] = a1[propName1]; // same error!
    
    在本例中,编译器看到您正在将
    a[K]
    类型的值赋给
    a[K]
    类型的值。这就是我建议你继续的方式


    好吧,希望这会有帮助;祝你好运


    如果编写
    const arr=[“some”,“strings”]
    编译器将推断
    arr
    属于
    string[]
    类型,它将立即忘记其内容的确切数字和值。这通常是正确的行为,因为人们确实倾向于改变数组的内容(即使是
    const
    的数组也可以有
    arr[0]=“赋值”
    arr.push(“push”);

    如果希望编译器跟踪数组文字中的特定内容,则需要更改声明变量的方式。最简单的方法是在TypeScript 3.4中介绍的:

    const arr = ["name", "length"] as const;
    
    现在已知
    arr
    的类型是一个长度为2的数组,其第一个元素必须是
    “name”
    ,第二个元素必须是
    “length”
    。因此,如果您编写
    arr.map(propName=>…)
    ,编译器将知道
    propName
    必须是
    “name”|“length”


    如果你解决了这个问题,你将面临的第二个问题是:

    这里的问题是编译器认为赋值可能不安全,因为它无法验证
    a2[propName]
    设置的属性与您从
    a1[propName]
    读取的属性完全相同。这对我们来说很明显,因为变量
    propName
    是相同的,但编译器看到的是这些访问使用相同的键类型,这是两种可能的联合,有四种可能的结果,如下所示:

    const propName2 = arr[Math.random() < 0.5 ? 0 : 1];
    const propName1 = arr[Math.random() < 0.5 ? 0 : 1];
    a2[propName2] = a1[propName1]; // same error!
    
    在本例中,编译器看到您正在将
    a[K]
    类型的值赋给
    a[K]
    类型的值。这就是我建议你继续的方式


    好吧,希望这会有帮助;祝你好运


    我最终使用的是将我的a1和a2对象强制转换为
    A&Record
    ,因为这是最优雅、对我来说最容易理解的解决方案

    const a1 = {
      name: "test",
      length: 2,
      thing: { whatever: true }
    } as A & Record<string, any>;
    
    const a2 = {
      name: "",
      length: 0,
      thing: { whatever: false }
    } as A & Record<string, any>;
    
    arr.filter(propName => propName in a2).forEach(propName => (a2[propName] = a1[propName]));
    
    
    const a1={
    名称:“测试”,
    长度:2,
    事情:{无论如何:真的}
    }作为记录;
    常数a2={
    姓名:“,
    长度:0,
    事情:{无论如何:错}
    }作为记录;
    arr.filter(a2.forEach中的propName=>propName)(propName=>(a2[propName]=a1[propName]);
    
    当然,在实际的生产解决方案中,我使用
    in
    type操作符首先检查字符串是否是对象中的实际字段名。
    if(a2中的“值”)等
    etc..

    我最终使用的是将a1和a2对象转换为
    A&Record
    ,因为这是最优雅的解决方案,对我来说也是可以理解的

    const a1 = {
      name: "test",
      length: 2,
      thing: { whatever: true }
    } as A & Record<string, any>;
    
    const a2 = {
      name: "",
      length: 0,
      thing: { whatever: false }
    } as A & Record<string, any>;
    
    arr.filter(propName => propName in a2).forEach(propName => (a2[propName] = a1[propName]));
    
    
    <