Search code examples
typescriptreact-nativeobjectindexingundefined

Type 'undefined' cannot be used as an index type


I am trying to convert a function from Javascript to Typescript but I keep running into the following error:

Type 'undefined' cannot be used as an index type

I understand that undefined cannot be used as an index, but I have tried the null check for the index type as well as conditional rendering but nothing seems to work.

Here is my code:

useState hook of values I am using for the function

const [newUser, setNewUser] = useState({
    firstName: "",
    lastName: "",
    companyName: "",
    email: "",
    password: "",
    id: ""
  });

const [errorMessage, setErrorMessage] = useState("");

function which is essentially taking the newUser initial values, making a copy of that object, then calling setNewUser to populate the fields entered by the user into a newUser copied object.

const setValues = (propName?: number, value?: any) => {
        const cloneUser = { ...newUser };
        cloneUser[propName] = value;
        setNewUser({ ... cloneUser });
        setErrorMessage("");
  }

My main issue is the cloneUser[propName] cannot be undefined and used as an index and I'm not sure how to get around this.


Solution

  • Answer

    Redefine the setValues function as:

    const setValue = (propName: keyof typeof newUser, value: string) => {
      // your update code here
    }
    

    The parameter types are changed to match your state type, which is inferred as:

    {
      firstName: string;
      lastName: string;
      companyName: string;
      email: string;
      password: string;
      id: string;
    }
    

    Alternatively

    Specify the type for state:

    type User = Readonly<{
      firstName: string;
      lastName: string;
      companyName: string;
      email: string;
      password: string;
      id: string;
    }>;
    
    // in the component
    const [newUser, setNewUser] = useState<User>({
      // initialize here
    });
    

    and define the function as:

    const setValue = (propName: keyof User, value: string) => { ... }
    

    Explanation

    The propName cannot be a number | undefined, since it is used to index an object with string keys (your state). It has to be a string.

    The problem that you are facing is caused by the propName parameter defined as propName?: number.

    This (propName?: number, value?: any) => { ... } is equivalent to (propName: number | undefined, value: any | undefined) => { ... }. This means that in your setValues function propName could be undefined, which is correctly detected as an error, as undefined value cannot be used to index an object.

    Suggestions

    I would also suggest to change the name of the function to setValue, as you are only setting one given property at the time.

    Additionally, you are setting string values, so the value can also be non-optional and typed as string.