Home > database >  How to fix Type 'null' cannot be used as an index type
How to fix Type 'null' cannot be used as an index type

Time:12-02

So I'm building a quiz app and that quiz is divided into difficulty levels. I change that level on a button click by setting params into my path. Then I try to insert a difficulty index because the structure of my obj is:

const questions = {
  easy: [...],
  medium: [...],
  hard: [...]
}

  const [searchParams, setSearchParams] = useSearchParams();
  const [currentPage, setCurrentPage] = useState(0);

  const difficulty = searchParams.get("difficulty");

  const handlePageChange = () => {
    if (currentPage   1 < questions[difficulty].length) {
      setCurrentPage((prevState) => prevState   1);
    }
  };

  const handleDifficultyChoice = (difficulty: DifficultyType) => {
    setSearchParams({ difficulty });
  };

Unfortunately I cannot insert that index because index cannot be null. How to solve that?

CodePudding user response:

You can replace the contents of the handlePageChange function with the following code, which will guarantee that difficulty is a valid property key in questions before executing the code after the conditional expression:

if (
  // This expresion evaluates to true or false,
  // depending on whether difficulty is a valid property key in questions:
  (difficulty as DifficultyType) in questions
  // If it evaluates to false, this one won't execute:
  && currentPage   1 < questions[difficulty as DifficultyType].length
  // and neither will the setCurrentPage invocation:
) setCurrentPage((prevState) => prevState   1);

Reference: The difficulty as DifficultyType syntax is what's called a type assertion.

Here's a full, reproducible example in the TypeScript Playground:

import {useState} from 'react';
import {useSearchParams} from 'react-router-dom';

const questions = {
  easy: [],
  medium: [],
  hard: []
};

type DifficultyType = keyof typeof questions;

function Component () {
  const [searchParams, setSearchParams] = useSearchParams();
  const [currentPage, setCurrentPage] = useState(0);

  const difficulty = searchParams.get("difficulty");

  const handlePageChange = () => {
    if (
      (difficulty as DifficultyType) in questions
      && currentPage   1 < questions[difficulty as DifficultyType].length
    ) setCurrentPage((prevState) => prevState   1);
  };

  const handleDifficultyChoice = (difficulty: DifficultyType) => {
    setSearchParams({ difficulty });
  };
}


See also: type guard functions in the TS handbook

CodePudding user response:

URLSearchParams.get returns a string value or null.

Check if difficulty is truthy prior to using it as a dynamic key.

Example:

const handlePageChange = () => {
  if (difficulty && currentPage   1 < questions[difficulty]?.length) {
    setCurrentPage((prevState) => prevState   1);
  }
};
  • Related