【问题标题】:How to combine object properties in typescript?如何在打字稿中组合对象属性?
【发布时间】:2016-08-30 18:27:58
【问题描述】:

我想知道最好的方法,比如我有两个对象

var objectA = {
    propertyA: 1,
    propertyB: 2
    ...
    propertyM: 13
}

var objectB = {
    propertyN: 14,
    propertyO: 15
    ...
    propertyZ: 26
}

如果objectC是由

创建的
var objectC = Object.assign(objectA, objectB);

如何声明/描述 objectC,以便编译器/IDE 知道它同时具有 objectA 和 objectB 的属性?

我想找到一种不需要为 objectA 和 objectB 定义接口的方法。我不想为同一个属性写两次声明和定义/评估。如果我在一个对象上有太多属性,这种冗余就很重要。

(有没有可以提取现有对象的接口/类型的算子?)

有可能吗?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    似乎这样可以解决问题:

    var objectA = {
        propertyA: 1,
        propertyB: 2,
        .
        . // more properties here
        .
        propertyM: 13
    };
    
    var objectB = {
        propertyN: 14,
        propertyO: 15,
        .
        . // more properties here
        .
        propertyZ: 26
    };
    
    var objectC = {...objectA, ...objectB}; // this is the answer
    
    var a = objectC.propertyA;
    
    var n = objectC.propertyN;
    

    根据这篇文章:https://blog.mariusschulz.com/2016/12/23/typescript-2-1-object-rest-and-spread


    此外,分解中变量的顺序很重要。 考虑以下几点:

    var objectA = {
        propertyA: 1,
        propertyB: 2, // same property exists in objectB
        propertyC: 3
    };
    
    var objectB = {
        propertyX: 'a',
        propertyB: 'b', // same property exists in objectA
        propertyZ: 'c'
    };
    
    // objectB will override existing properties, with the same name,
    // from the decomposition of objectA
    var objectC = {...objectA, ...objectB}; 
    
    // result: 'b'
    console.log(objectC.propertyB); 
    
    // objectA will override existing properties, with the same name,
    // from the decomposition of objectB
    var objectD = {...objectB, ...objectA}; 
    
    // result: '2'
    console.log(objectD.propertyB); 
    

    【讨论】:

    • 只是为了改进答案:这一行可以解决问题: var objectC = {...objectA, ...objectB};
    • 如果两个对象中存在相同的键,我想更新 objectA 的属性。意味着如果键相同,那么它应该具有objectB的属性。这怎么可能?
    • 阅读我的回答中的 cmets。基本上,它从左到右构造属性,其中每个新信息都会覆盖现有信息:var objectC = {...objectA, ...objectB};。如果属性名称相同,objectB 中的属性将覆盖已经从objectA 分配的属性。
    • 这行得通,因此回答了 OP,但是我担心现在没有与 objectD 或 objectC 关联的类型,当您尝试将其显式键入某些东西时(假设有这样的类型),它不会工作。有类型安全的方法吗?
    • @SrivathsaHarishVenkataramana 类型是从分配中推断出来的。所以 objectC 将有propertyB: string,而 objectD 将推断它为propertyB: number。您可以手动输入 C 和 D:type ABC = { propertyA: number; propertyB: string | number; propertyC: number; propertyX: string; propertyZ: string; } 或通过将 propertyB 设置为字符串或数字来仅输入其中之一。
    【解决方案2】:

    所以编译器/IDE 知道它同时具有 objectA 和 objectB 的属性?

    使用交集类型 + 泛型。例如。 from here

    /**
     * Quick and dirty shallow extend
     */
    export function extend<A>(a: A): A;
    export function extend<A, B>(a: A, b: B): A & B;
    export function extend<A, B, C>(a: A, b: B, c: C): A & B & C;
    export function extend<A, B, C, D>(a: A, b: B, c: C, d: D): A & B & C & D;
    export function extend(...args: any[]): any {
        const newObj = {};
        for (const obj of args) {
            for (const key in obj) {
                //copy all the fields
                newObj[key] = obj[key];
            }
        }
        return newObj;
    };
    

    更多

    这里都提到了:https://basarat.gitbooks.io/typescript/content/docs/types/type-system.html

    【讨论】:

    • 谢谢。这似乎有效。但是,extend() 函数是在第 3 方库中定义的,有没有办法在其 d.ts 文件中覆盖 extend() 的这个特定定义? (我正在使用下划线 _.extend() )。
    • 是的。只需修改underscore.d.ts
    【解决方案3】:

    (是否有可以提取接口/类型的运算符 现有对象?有可能吗?)

    你应该选择typeof

    type typeA = typeof objectA;
    type typeB = typeof objectB;
    

    要使它们合并,您可以使用 basarat 已经指出的交集操作。

    type typeC = typeA & typeB
    

    【讨论】:

      【解决方案4】:

      使用Typescript spread operator 转译为Javascript Object.assign()

      如果您需要深度树对象合并,您可以使用 best-global 包的更改功能

      【讨论】:

        【解决方案5】:

        试试这个..

        const person = { name: 'TRilok', gender: 'Male' };
        const tools = { computer: 'Mac', editor: 'Atom' };
        const attributes = { handsomeness: 'Extreme', hair: 'Brown', eyes: 'Blue' };
        
        const summary = {...person, ...tools, ...attributes};
        

        【讨论】:

          【解决方案6】:

          Lodash 有一个“扩展”功能,可以组合对象并让 Typescirpt 知道新对象具有您期望的类型。

          const a = { one: 1, two: 2 };
          const b = { three: 3, four: 4 };
          const c = lodash.extend(a, b);
          // c: { one: 1, two: 2, three: 3, four: 4 }
          

          【讨论】:

            猜你喜欢
            • 2022-12-14
            • 1970-01-01
            • 2021-04-23
            • 2021-12-17
            • 1970-01-01
            • 2019-05-17
            • 1970-01-01
            • 2018-08-03
            • 1970-01-01
            相关资源
            最近更新 更多