0

I'm building an educational quiz app with typescript and react. In order to generate random questions I need to pick a key value object from a larger object at random.

Here is an example of the object I'm working with:

  verb: {
      "plural": {
        "first": {
          "cz": {
            "verb": "mám"
          },
          "en": {
            "verb": "have"
          }
        },
        "third": {
          "cz": {
            "verb": "mají"
          },
          "en": {
            "verb": "have"
          }
        },
        "second": {
          "cz": {
            "verb": "máte"
          },
          "en": {
            "verb": "have"
          }
        }
      },
      "singular": {
        "first": {
          "cz": {
            "verb": "mám"
          },
          "en": {
            "verb": "have"
          }
        },
        "third": {
          "cz": {
            "verb": "má"
          },
          "en": {
            "verb": "has"
          }
        },
        "second": {
          "cz": {
            "verb": "jsi"
          },
          "en": {
            "verb": "máš"
          }
        }
      }
    }

One method I've been attempting has been creating variables to randomly be assigned "plural" or "singular" and "first", "second" and "third". And then using these variables in bracket annotation within a dot annotation to pull the object at random from the object.

Here is an example of what I've been trying:

//function to return random number
const random = (arrayLength: number) => Math.floor(Math.random() * arrayLength);
//random variable setters
const amount = ["singular", "plural"][random(2)]
const person = ["first", "second", "third"][random(3)]
//dot/bracket annotation to return random object
const randomObject = verb[amount][person]

This is working and returning the random object as I wanted but I am getting TS: error ts(7053)

The error returns:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ plural: { first: { en: { verb: string; }; cz: { verb: string; }; }; second: { en: { verb: string; }; cz: { verb: string; }; }; third: { en: { verb: string; }; cz: { verb: string; }; }; }; singular: { first: { en: { verb: string; }; cz: { ...; }; }; second: { ...; }; third: { ...; }; }; }'.
  No index signature with a parameter of type 'string' was found on type '{ plural: { first: { en: { verb: string; }; cz: { verb: string; }; }; second: { en: { verb: string; }; cz: { verb: string; }; }; third: { en: { verb: string; }; cz: { verb: string; }; }; }; singular: { first: { en: { verb: string; }; cz: { ...; }; }; second: { ...; }; third: { ...; }; }; }'.ts(7053)

If possible I would love some feedback on this approach I've used in order to get an object at random from within an object and whether this is a good approach or not. I would also like some help solving this TS error that I'm getting.

Many thanks.

  • 1
    Declare the arrays `as const` so they don't get widened to `string[]` – CertainPerformance Feb 21 '23 at 00:05
  • @CertainPerformance When I write : const amount = ["singular", "plural"][random(2)] as const; I get the error: A 'const' assertions can only be applied to references to enum members, or string, number, boolean, array, or object literals. – Ruairidh Grass Feb 21 '23 at 00:20
  • You need to apply it to the array there so it doesn't get widened to `string[]` - so `["singular", "plural"] as const` – CertainPerformance Feb 21 '23 at 00:52

0 Answers0