Как объединить свойства объекта в машинописном тексте?

83

Я хотел бы знать, как это сделать, скажем, у меня есть два объекта

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. Я не хочу дважды писать декларацию и определение / оценку для одного и того же свойства. Эта избыточность важна, если у меня слишком много свойств объекта.

(Есть ли оператор, который может извлечь интерфейс / тип существующего объекта?)

Является ли это возможным?

WawaBrother
источник

Ответы:

161

Похоже, это должно помочь:

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); 
Алькасай
источник
4
просто чтобы улучшить ответ: эта строка делает фокус: var objectC = {... objectA, ... objectB};
Амирреза
Я хочу обновить свойство объекта A, если в обоих объектах существует один и тот же ключ. Значит, если ключ такой же, то он должен принимать свойство objectB. Как это возможно?
Анкур Аквалия
Прочтите комментарии в моем ответе. В основном он создает свойства слева направо, где каждая новая информация перегружает существующий: var objectC = {...objectA, ...objectB};. Форма objectBсвойств переопределит свойства, которые уже были назначены из objectA, если свойства имеют то же имя.
Alkasai
Это работает, поэтому отвечает 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; }или только один из них, установив для свойстваB значение string или number.
Alkasai
10

значит, компилятор / IDE знает, что у него есть свойства как objectA, так и objectB?

Используйте тип пересечения + универсальные. Например, отсюда

/**
 * 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 () определена в сторонней библиотеке, есть ли способ перезаписать это конкретное определение для extend () в его файле d.ts? (Я использую подчеркивание _.extend ()).
WawaBrother
Ага. Просто доработайтеunderscore.d.ts
басарат 05
4

(Есть ли оператор, который может извлечь интерфейс / тип существующего объекта? Возможно ли это?)

Вам следует выбрать typeof .

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

Чтобы их объединить, вы можете использовать операцию пересечения, как уже указывал басарат.

type typeC = typeA & typeB
Hav
источник
3

попробуй это..

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};
Трилок Сингх
источник