Home > Mobile >  Type 'undefined' cannot be used as an index type
Type 'undefined' cannot be used as an index type

Time:12-15

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.

CodePudding user response:

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, because 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.

CodePudding user response:

Looks like you're trying to arbitrarily add a key value pair to this object with a numeric key and any value. You need to tell typescript that this is allowed by defining a type, and passing it to the generic parameter of useState.

demo: https://stackblitz.com/edit/react-ts-mpdukw?file=App.tsx

type User = {
  firstName: string;
  lastName: string;
  companyName: string;
  email: string;
  password: string;
  id: string;
  [key: number]: any; // This lets you add a numeric key with any value
};
  // generic parameter defines the type of `newUser`
  const [newUser, setNewUser] = useState<User>({
    firstName: '',
    lastName: '',
    companyName: '',
    email: '',
    password: '',
    id: '',
  });

Then, it doesn't make sense to allow an undefined key, so make that property mandatory:

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

Depending on the use case, you may want to allow an undefined key and just skip steps in that case.

  const setValues = (propName?: number, value?: any) => {
    if (propName) setNewUser({ ...newUser, [propName]: value });
    setErrorMessage('');
  };
  • Related