Home > database >  using a array to access state object on condition using typescript?
using a array to access state object on condition using typescript?

Time:07-19

I have the following object with an extended state object, I made an array of values that I want to check using a for of loop and check the state object's current value, issue is I cannot make the array value compatible with state object key, how to make them fit telling typescript that the value is a compatible key for the state object ?

const inicialState = {
  a: true
  b: true
  c: false
  d: true
  e: true
};

const [type, setType] = useState < typeof inicialState > (inicialState);

const requirments = ['a', 'n', 'c'];
for (const value of requirments) {
  if (!type[value] /* Cannot acces object key */ ) {
    console.log('false')
  }
}

CodePudding user response:

There's a number of ways you can solve this problem.

Your requirements array is inferred as a string[], but what you want it to actually represent is "an array of the possible keys in inicialState; you can use keyof and typeof to help here:

const requirments: (keyof typeof inicialState)[] = ['a', 'n', 'c'];

However, now you'll be warned that n isn't a valid key (which it isn't!) - so you either need to give n an initial value:

const inicialState: InicialState = {
  a: true,
  b: true,
  c: false,
  d: true,
  e: true,
  n: undefined,
};

Or better still, if your set of keys is fixed, then you should create a type / interface that describes the inicialState:

interface InicialState {
  a: boolean;
  b: boolean;
  c: boolean;
  d: boolean;
  e: boolean;
  n?: boolean;
};

const inicialState: InicialState = {
  // ...
};

const requirments: (keyof InicialState)[] = ['a', 'n', 'c'];

And if the set of keys is not fixed then you can use Record<string, boolean>:

const inicialState: Record<string, boolean> = {
  a: true,
  b: true,
  c: false,
  d: true,
  e: true,
};

CodePudding user response:

I guess the idea is that your requirements array is dynamic (we cannot guarantee that everything in that array is a key of type), so typescript is just warning you (or throwing error if you in strict mode) about that. A work around is to use Object.keys to check if a string exists in an object key: Update: at this point typescript still cannot infer that the value here is a keyof inicialState so we just kinda have to help it a little bit

if (Object.keys(type).includes(value)) {
  console.log(type[value as keyof typeof inicialState]);
}

Another way is to annotate the type to be an object with that could have any string for it keys:

const inicialState: Record<string, boolean> = {
    a: true,
    b: true,
    c: false,
    d: true,
    e: true
};

CodePudding user response:

type ObjectKey = keyof typeof type;

const requirments = ['a', 'b', 'c'] as ObjectKey[];

for (const value of requirments) {
  if (!type[value]) {
    console.log(false)
  }
}

  • Related