TypeScript'te nesne özellikleri nasıl birleştirilir?


83

Bunu yapmanın en iyi yolunu bilmek istiyorum, diyelim ki iki nesnem var

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

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

ObjectC, tarafından oluşturulursa

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

ObjectC'yi nasıl açıklayabilirim / açıklayabilirim, böylece derleyici / IDE hem objectA hem de objectB özelliklerine sahip olduğunu bilir?

ObjectA ve objectB için arayüz tanımlamaya gerek kalmadan bir yol bulmak istiyorum. Aynı mülk için iki kez beyan ve tanım / değerlendirme yazmak istemiyorum. Bir nesnede çok fazla özelliğim varsa bu fazlalık önemlidir.

(Mevcut bir nesnenin arayüzünü / türünü çıkarabilen bir operatör var mı?)

Mümkün mü?

Yanıtlar:


161

Görünüşe göre bu hile yapmalı:

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;

Bu makaleye dayanarak: https://blog.mariusschulz.com/2016/12/23/typescript-2-1-object-rest-and-spread


Ek olarak, ayrıştırmadaki değişkenlerin sırası önemlidir. Aşağıdakileri göz önünde bulundur:

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
sadece yanıtı iyileştirmek için: bu satır hile yapıyor: var objectC = {... objectA, ... objectB};
Amirreza

Her iki nesnede de aynı anahtar varsa, objectA'nın özelliğini güncellemek istiyorum. Anahtar aynıysa, objectB'nin özelliğini alması gerektiği anlamına gelir. Bu nasıl mümkün olaiblir?
Ankur Akvaliya

Cevabımdaki yorumları okuyun. Her yeni bilgi mevcut bir geçersiz kılar sağ soldan Temel olarak özelliklerini oluşturur: var objectC = {...objectA, ...objectB};. Özellikler formu objectB, özellikler objectAaynı ada sahipse, önceden atanmış olan özellikleri geçersiz kılar .
Alkasai

Bu işe yarıyor, bu nedenle OP yanıtını veriyor, ancak benim endişem şu anda objectD veya objectC ile ilişkili bir tür olmaması, onu açıkça bir şeye yazmaya çalıştığınızda (böyle bir tür olduğunu varsayın) işe yaramayacak. Bunu yapmanın güvenli bir yolu var mı?
Srivathsa Harish Venkataramana

@SrivathsaHarishVenkataramana türler atamadan çıkarılır. Yani, objectC'ye sahip olacak propertyB: string, objectD ise bunu çıkaracaktır propertyB: number. Her ikisini de manuel olarak yazabilirsiniz: type ABC = { propertyA: number; propertyB: string | number; propertyC: number; propertyX: string; propertyZ: string; }veya özellikB'yi dize veya sayı olarak ayarlayarak bunlardan yalnızca birini yazabilirsiniz .
Alkasai

10

yani derleyici / IDE hem objectA hem de objectB özelliklerine sahip olduğunu biliyor mu?

Bir kesişim türü + jenerik kullanın. Örneğin buradan

/**
 * 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;
};

Daha

Her ikisinden de burada bahsedilmektedir: https://basarat.gitbooks.io/typescript/content/docs/types/type-system.html


Teşekkürler. Bu işe yarıyor gibi görünüyor. Bununla birlikte, ext () işlevi bir üçüncü taraf kitaplığında tanımlanmıştır, d.ts dosyasında ext () için bu belirli tanımın üzerine yazmanın herhangi bir yolu var mı? (Alt çizgi _.extend () kullanıyorum).
WawaBrother

Evet. Sadece değiştirinunderscore.d.ts
basarat

4

(Mevcut bir nesnenin arayüzünü / türünü çıkarabilen bir operatör var mı? Mümkün mü?)

Typeof için gitmelisin .

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

Onları birleştirmek için, basarat'ın daha önce de belirttiği gibi, kesişme işlemini kullanabilirsiniz.

type typeC = typeA & typeB


3

bunu dene..

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};
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.