Type ... is missing the following properties from type ... assigning key and value in empty object using index signature faced error

93 views Asked by At

I am trying to create it where the object keys are unknown in the beginning (util I got testArray from the previous page).

{
  a: [ { key1: 0, key2: 0 }, { key1: 0, key2: 0 }, { key1: 0, key2: 0 } ],
  b: [ { key1: 0, key2: 0 }, { key1: 0, key2: 0 }, { key1: 0, key2: 0 } ]
}
interface DemoObject {
  [key: string]: Array<{
    key1: number;
    key2: number;
  }>;
}

const testArray = ["a", "b"];
const innerKeys = ["key1", "key2"];
const demoObject: DemoObject = {};

testArray.forEach((t: string) => {
  demoObject[t] = Array.from({ length: 3 }, () =>
    Object.fromEntries(innerKeys.map((prop) => [prop, 0]))
  );
});

However, I got these two error at object[t]:

Type '{ [k: string]: number; }[]' is not assignable to type '{ key1: number; key2: number; }[]'.
Type '{ [k: string]: number; }' is missing the following properties from type '{ key1: number; key2: number; }': key1, key2
1

There are 1 answers

0
wonderflame On

First of all, innerKeys should be narrowed, since currently, its type is string[]. This can be done by using the const assertion:

// readonly ["key1", "key2"]
const innerKeys = ['key1', 'key2'] as const;

//  "key1" | "key2"
type InnerKey = typeof innerKeys[number];

Another problem is that Object.fromEntries() is not return the literal type. The easiest fix would be to use as assertion to cast it to the correct type, or by using this answer we can create a typed version of the method, though it also calls the assertion at the end.

Testing:

testArray.forEach((t) => {
  demoObject[t] = Array.from({ length: 3 }, () =>
    createTypedObjectFromEntries(innerKeys.map((prop) => [prop, 0])),
  );
});

playground