Home > Enterprise >  Unable to assign value of original type in Array.reduce function
Unable to assign value of original type in Array.reduce function

Time:02-06

I'm creating a function which takes a boolean indicator object like:

const fruits = {
  apple: false,
  banana: false,
  orange: false,
  mango: false,
};

And an array like ['apple', 'orange']. It should return object similar in structure of input object with properties in array turned true.

I've these typescript functions to achieve it


// Helper function to type Object.Keys
const objectKeysTyped = <Obj extends object>(obj: Obj) => {
  return Object.keys(obj) as (keyof Obj)[];
};

// Main function
const arrayToBoolIndicator = <Obj extends Record<string, boolean>>(
  boolFramework: Obj,
  arrayOfIncluded: (keyof Obj)[]
) => {
  return objectKeysTyped(boolFramework).reduce(
    (acc, cur) => {

      // TS Error next line: Type 'boolean' is not assignable to type 'Obj[keyof Obj]'.
      acc[cur] = arrayOfIncluded.includes(cur); 

      return acc;
    },
    { ...boolFramework }
  );
};

Typescript Playground link

Why am I getting the TS error while I'm assigning original type to object's property?

CodePudding user response:

The compiler cannot guarantee that boolean is assignable to the properties of Obj; all we know is the reverse. This is a concern because there exist true and false literal types which are more specific than boolean. If you have a property of type true then you can't safely assign a boolean value to it because that value might be false. Similarly if you have a property of type false then you can't sagely assign a boolean value to it because that value might be true. Thus the compiler complains about assigning a boolean value to acc[cur].

For example:

const x = { a: true, b: false } as const;
/* const x: { readonly a: true; readonly b: false; } */

const y = arrayToBoolIndicator(x, ["b"]);
// const y: { readonly a: true; readonly b: false; }
console.log(y);  // {a: false, b: true}, uh oh
(y.a && "abc").toUpperCase(); // compiles fine, but            
  • Related