admin管理员组

文章数量:1326299

I'm trying to be cute with TypeScript and arrays and use the spread operator to essentially prepend an object to an array of objects.

Here's the setup:

Interface to define my types:

interface KeyValuePair {
  key: string;
  value: string;
}

An array of objects of type:

const kvpset: KeyValuePair[] = [
  { key: "1", value: "One" },
  { key: "2", value: "Two" },
  { key: "3", value: "Three" },
  { key: "4", value: "Four" },
  { key: "5", value: "Five" },
  { key: "6", value: "Six" },
  { key: "7", value: "Seven" },
  { key: "8", value: "Eight" },
  { key: "9", value: "Nine" },
];

My prepend typed object thingy:

const kvpzero: KeyValuePair = { key: "0", value: "Zero" };

First try:

const kvpAll: KeyValuePair[] = { kvpzero, ...kvpset };

Error in the editor:

property) kvpzero: KeyValuePair Type '{ length: number; toString(): string; toLocaleString(): string; pop(): KeyValuePair; push(...items: KeyValuePair[]): number; concat(...items: ConcatArray[]): KeyValuePair[]; concat(...items: (KeyValuePair | ConcatArray<...>)[]): KeyValuePair[]; ... 26 more ...; kvpzero: KeyValuePair; }' is not assignable to type 'KeyValuePair[]'. Object literal may only specify known properties, and 'kvpzero' does not exist in type 'KeyValuePair[]'.ts(2322)

Okay, so I'm a bit clueless. I'll try this:

const kvpzeroAsArray: KeyValuePair[] = [{ key: "0", value: "Zero" }];

and this doesn't give a "piler error":

const kvpAll: KeyValuePair[] = { ...kvpzeroAsArray, ...kvpset };

Using tsc and node to run it (editor is Visual Studio Code). Results in a console.log() for the kvpAll object:

kvpAll is {
  '0': { key: '1', value: 'One' },
  '1': { key: '2', value: 'Two' },
  '2': { key: '3', value: 'Three' },
  '3': { key: '4', value: 'Four' },
  '4': { key: '5', value: 'Five' },
  '5': { key: '6', value: 'Six' },
  '6': { key: '7', value: 'Seven' },
  '7': { key: '8', value: 'Eight' },
  '8': { key: '9', value: 'Nine' }
}

Three things that I see here. One, the object is now an object and not an array. Two, my zero is missing.I have no idea why this doesn't work or why I can't get the expected results. Three, it's not even the same type of output I wanted. It has the property as a number with the value as the object. '0': { key: '1', value: 'One' } instead of just { key: '1', value: 'One' }.

Searching on the web, it seems that maybe the Object.assign() mechanism is a way to go.

const assignedkvp = (<any>Object).assign(kvpzeroAsArray, kvpset);

Output (via a console.log() again):

assignedkvp is [
  { key: '1', value: 'One' },
  { key: '2', value: 'Two' },
  { key: '3', value: 'Three' },
  { key: '4', value: 'Four' },
  { key: '5', value: 'Five' },
  { key: '6', value: 'Six' },
  { key: '7', value: 'Seven' },
  { key: '8', value: 'Eight' },
  { key: '9', value: 'Nine' }
]

Hmm...similar results as the spread. The object doesn't get changed as the spread changes it, but I still don't see my desired pretending result.

I'm at a loss at this point. I don't understand how I can use the spread operator or the assign function and get the desired results. I'd appreciate any insight. Here's my current solution. The brute force method:

const prePendObjectToArray = <T>(object: T, array: T[]): T[] => {
  let returnArray = [] as T[];

  if (array && array.length > 0 && object) {
    for (let i = 0; i < array.length + 1; i++) {
      if (i === 0) {
        returnArray.push(object);
      } else {
        returnArray.push(array[i - 1]);
      }
    }
  }

  return returnArray;
};

Usage:

const newArray = prePendObjectToArray(kvpzero, kvpset);
console.log(newArray);

Result:

[
  { key: '0', value: 'Zero' },
  { key: '1', value: 'One' },
  { key: '2', value: 'Two' },
  { key: '3', value: 'Three' },
  { key: '4', value: 'Four' },
  { key: '5', value: 'Five' },
  { key: '6', value: 'Six' },
  { key: '7', value: 'Seven' },
  { key: '8', value: 'Eight' },
  { key: '9', value: 'Nine' }
]

If there is a better way, I'd appreciate knowing what I'm missing.

I'm trying to be cute with TypeScript and arrays and use the spread operator to essentially prepend an object to an array of objects.

Here's the setup:

Interface to define my types:

interface KeyValuePair {
  key: string;
  value: string;
}

An array of objects of type:

const kvpset: KeyValuePair[] = [
  { key: "1", value: "One" },
  { key: "2", value: "Two" },
  { key: "3", value: "Three" },
  { key: "4", value: "Four" },
  { key: "5", value: "Five" },
  { key: "6", value: "Six" },
  { key: "7", value: "Seven" },
  { key: "8", value: "Eight" },
  { key: "9", value: "Nine" },
];

My prepend typed object thingy:

const kvpzero: KeyValuePair = { key: "0", value: "Zero" };

First try:

const kvpAll: KeyValuePair[] = { kvpzero, ...kvpset };

Error in the editor:

property) kvpzero: KeyValuePair Type '{ length: number; toString(): string; toLocaleString(): string; pop(): KeyValuePair; push(...items: KeyValuePair[]): number; concat(...items: ConcatArray[]): KeyValuePair[]; concat(...items: (KeyValuePair | ConcatArray<...>)[]): KeyValuePair[]; ... 26 more ...; kvpzero: KeyValuePair; }' is not assignable to type 'KeyValuePair[]'. Object literal may only specify known properties, and 'kvpzero' does not exist in type 'KeyValuePair[]'.ts(2322)

Okay, so I'm a bit clueless. I'll try this:

const kvpzeroAsArray: KeyValuePair[] = [{ key: "0", value: "Zero" }];

and this doesn't give a "piler error":

const kvpAll: KeyValuePair[] = { ...kvpzeroAsArray, ...kvpset };

Using tsc and node to run it (editor is Visual Studio Code). Results in a console.log() for the kvpAll object:

kvpAll is {
  '0': { key: '1', value: 'One' },
  '1': { key: '2', value: 'Two' },
  '2': { key: '3', value: 'Three' },
  '3': { key: '4', value: 'Four' },
  '4': { key: '5', value: 'Five' },
  '5': { key: '6', value: 'Six' },
  '6': { key: '7', value: 'Seven' },
  '7': { key: '8', value: 'Eight' },
  '8': { key: '9', value: 'Nine' }
}

Three things that I see here. One, the object is now an object and not an array. Two, my zero is missing.I have no idea why this doesn't work or why I can't get the expected results. Three, it's not even the same type of output I wanted. It has the property as a number with the value as the object. '0': { key: '1', value: 'One' } instead of just { key: '1', value: 'One' }.

Searching on the web, it seems that maybe the Object.assign() mechanism is a way to go.

const assignedkvp = (<any>Object).assign(kvpzeroAsArray, kvpset);

Output (via a console.log() again):

assignedkvp is [
  { key: '1', value: 'One' },
  { key: '2', value: 'Two' },
  { key: '3', value: 'Three' },
  { key: '4', value: 'Four' },
  { key: '5', value: 'Five' },
  { key: '6', value: 'Six' },
  { key: '7', value: 'Seven' },
  { key: '8', value: 'Eight' },
  { key: '9', value: 'Nine' }
]

Hmm...similar results as the spread. The object doesn't get changed as the spread changes it, but I still don't see my desired pretending result.

I'm at a loss at this point. I don't understand how I can use the spread operator or the assign function and get the desired results. I'd appreciate any insight. Here's my current solution. The brute force method:

const prePendObjectToArray = <T>(object: T, array: T[]): T[] => {
  let returnArray = [] as T[];

  if (array && array.length > 0 && object) {
    for (let i = 0; i < array.length + 1; i++) {
      if (i === 0) {
        returnArray.push(object);
      } else {
        returnArray.push(array[i - 1]);
      }
    }
  }

  return returnArray;
};

Usage:

const newArray = prePendObjectToArray(kvpzero, kvpset);
console.log(newArray);

Result:

[
  { key: '0', value: 'Zero' },
  { key: '1', value: 'One' },
  { key: '2', value: 'Two' },
  { key: '3', value: 'Three' },
  { key: '4', value: 'Four' },
  { key: '5', value: 'Five' },
  { key: '6', value: 'Six' },
  { key: '7', value: 'Seven' },
  { key: '8', value: 'Eight' },
  { key: '9', value: 'Nine' }
]

If there is a better way, I'd appreciate knowing what I'm missing.

Share Improve this question asked Oct 29, 2020 at 12:54 Dan7elDan7el 2,0576 gold badges25 silver badges47 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 5
const kvpAll: KeyValuePair[] = { ...kvpzeroAsArray, ...kvpset };

This is not an array. You are spreading into an object.

Do:

const kvpAll: KeyValuePair[] = [ ...kvpzeroAsArray, kvpset ];

本文标签: javascriptTypeScript add object to array with spreadStack Overflow