Làm thế nào để kết hợp các thuộc tính đối tượng trong bảng chữ?


82

Tôi muốn biết cách tốt nhất để làm điều này, giả sử tôi có hai đối tượng

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

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

Nếu objectC được tạo bởi

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

Làm cách nào để khai báo / mô tả objectC, để trình biên dịch / IDE biết rằng nó có các thuộc tính của cả objectA và objectB?

Tôi muốn tìm một cách mà không cần xác định giao diện cho objectA và objectB. Tôi không muốn viết khai báo và định nghĩa / đánh giá cho cùng một thuộc tính hai lần. Sự dư thừa này là đáng kể nếu tôi có quá nhiều thuộc tính trên một đối tượng.

(Có toán tử nào có thể trích xuất giao diện / kiểu của một đối tượng hiện có không?)

Nó có khả thi không?

Câu trả lời:


155

Có vẻ như điều này nên thực hiện mẹo:

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;

Dựa trên bài viết này: https://blog.mariusschulz.com/2016/12/23/typescript-2-1-object-rest-and-spread


Ngoài ra, thứ tự của các biến trong phân rã cũng quan trọng. Hãy xem xét những điều sau:

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
chỉ để cải thiện câu trả lời: dòng này thực hiện thủ thuật: var objectC = {... objectA, ... objectB};
— Amirreza

Tôi muốn cập nhật thuộc tính của objectA nếu cùng một khóa tồn tại trong cả hai đối tượng. Có nghĩa là nếu key giống nhau thì nó sẽ lấy thuộc tính của objectB. Làm thế nào là nó có thể?
— Ankur Akvaliya

Đọc các bình luận trong câu trả lời của tôi. Về cơ bản nó xây dựng các thuộc tính từ trái sang phải, nơi mà mỗi thông tin mới ghi đè lên một hiện: var objectC = {...objectA, ...objectB};. Biểu mẫu thuộc tính objectBsẽ ghi đè các thuộc tính đã được gán từ đó objectA, nếu các thuộc tính có cùng tên.
— Alkasai

Điều này hoạt động, do đó trả lời OP, tuy nhiên mối quan tâm của tôi là không có kiểu nào được liên kết với objectD hoặc objectC, khi bạn cố gắng gõ rõ ràng nó vào một thứ gì đó (giả sử có một kiểu như vậy), nó sẽ không hoạt động. Có loại cách nào an toàn để làm điều này không?
— Srivathsa Harish Venkataramana

@SrivathsaHarishVenkataramana các kiểu được suy ra từ phép gán. Vì vậy objectC sẽ có propertyB: string, trong khi objectD sẽ suy ra nó là propertyB: number. Bạn có thể nhập thủ công cả C & D: type ABC = { propertyA: number; propertyB: string | number; propertyC: number; propertyX: string; propertyZ: string; }hoặc chỉ một trong số chúng bằng cách đặt thuộc tínhB thành chuỗi hoặc thành số.
— Alkasai

10

để trình biên dịch / IDE biết rằng nó có các thuộc tính của cả objectA và objectB?

Sử dụng loại giao nhau + số liệu chung. Vd từ đây

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

Hơn

Cả hai đều được đề cập ở đây: https://basarat.gitbooks.io/typescript/content/docs/types/type-system.html


Cảm ơn. Điều này có vẻ hiệu quả. Tuy nhiên, hàm expand () được định nghĩa trong thư viện của bên thứ 3, có cách nào để ghi đè định nghĩa cụ thể này cho hàm expand () trong tệp d.ts của nó không? (Tôi đang sử dụng dấu gạch dưới _.extend ()).
— WawaBrother

Đúng vậy. Chỉ cần sửa đổiunderscore.d.ts
— basarat

4

(Có toán tử nào có thể trích xuất giao diện / kiểu của một đối tượng hiện có không? Có thể không?)

Bạn nên sử dụng typeof .

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

Để hợp nhất chúng, bạn có thể sử dụng thao tác giao nhau như dấu ba phân đã được chỉ ra.

type typeC = typeA & typeB


3

thử đi..

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};
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookie và Chính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.