Type 'X' cannot be used as an index type in TypeScript

avatar
Borislav Hadzhiev

Last updated: Feb 28, 2024
5 min

banner

# Table of Contents

  1. Type 'X' cannot be used as an index type in TypeScript
  2. Type 'undefined' cannot be used as an index type in TS

If you got the error "Type 'undefined' cannot be used as an index type", click on the second subheading.

# Type 'X' cannot be used as an index type in TypeScript

The error "Type cannot be used as an index type" occurs when we try to use a type that cannot be used to index an array or object, e.g. one of the non-primitive types like String.

To solve the error, use primitive (lowercase) types, e.g. number or string when typing values.

Here is an example of how the error occurs.

index.ts
const obj = { name: 'Bobby Hadz', } // ๐Ÿ‘‡๏ธ using String (capital S) const str: String = 'name'; // โ›”๏ธ Error: Type 'String' cannot be used as an index type.ts(2538) obj[str]

We used the String non-primitive object type to type the str variable, which caused the error.

We can't use the non-primitive types, like Number, String, Boolean or Object as index types.

# Use the lowercase primitive types to solve the error

To solve the error, always use the number, string, boolean, Record, types instead.

index.ts
interface Employee { name: string; // ๐Ÿ‘ˆ๏ธ use string lowercase s } const obj: Employee = { name: 'Bobby Hadz', }; const str = 'name'; console.log(obj[str]); // ๐Ÿ‘‰๏ธ "Bobby Hadz"

use lowercase primitive types to solve the error

The code for this article is available on GitHub

We used the primitive string type to solve the error.

The error is caused because there is a difference between the primitive number, string and boolean types and the non-primitive Number, String, Boolean, Object, etc.

The non-primitive types are objects and should never be used when typing values in TypeScript.

The TypeScript best practices documentation warns to never use the Number, String, Boolean, Symbol or Object non-primitive objects when typing values in your TypeScript code.

Instead, you should be using number, string, boolean, symbol and Record types.

The error message means that you can't use the specified type when trying to index an array or object in TypeScript.

# Another example of how the error occurs

Here is another example of how the error occurs.

index.ts
interface Person { key: String; // ๐Ÿ‘ˆ๏ธ should be string } const obj1: Person = { key: 'name', }; const obj2 = { name: 'Bobby Hadz', }; // โ›”๏ธ Error: Type 'String' cannot be used as an index type.ts(2538) obj2[obj1.key]

The code sample shows how using the String non-primitive, object type causes an error because it can't be used to index the object at a specific property.

index.ts
interface Person { key: string; // ๐Ÿ‘ˆ๏ธ using primitive type } const obj1: Person = { key: 'name', }; const obj2 = { name: 'Bobby Hadz', }; // โœ… Works console.log(obj2[obj1.key as keyof typeof obj2]); // ๐Ÿ‘‰๏ธ "Bobby Hadz"

using string primitive type

The code for this article is available on GitHub

Using the string primitive type resolved the issue.

The cause of the error is shown when you try to assign a value of type String to a value of type string.

index.ts
const str1: String = 'bobbyhadz.com'; // โ›”๏ธ Error: Type 'String' is not assignable to type 'string'. // 'string' is a primitive, but 'String' is a wrapper object. // Prefer using 'string' when possible. const str2: string = str1;

The capitalized non-primitive objects like String, Number, Boolean, Symbol and Object are not equivalent to string, number, boolean, etc.

Make sure to always use number, string, boolean, symbol and Record instead.

# Type 'undefined' cannot be used as an index type in TS

The "Type 'undefined' cannot be used as an index type" error occurs when a value that is possibly undefined is used to index an object or array.

To solve the error, use a type guard to make sure the value is not undefined before indexing the object or array.

Here is an example of how the error occurs.

index.ts
// ๐Ÿ‘‡๏ธ key is optional (could be undefined) const obj1: { key?: string } = { key: 'name', }; const obj2 = { name: 'Bobby Hadz', }; // โ›”๏ธ Error: Type 'undefined' cannot be used as an index type.ts(2538) const result = obj2[obj1.key];

We used a question mark to mark the key property as optional in the obj1 variable.

This means that the obj1.key property could be a string or it could have an undefined value.

With the error message, TypeScript tells us that we can't use an undefined value to index the object.

# Use a type guard to solve the error

To solve the error, check if the value is not undefined before accessing the property.

index.ts
// ๐Ÿ‘‡๏ธ key is optional (could be undefined) const obj1: { key?: string } = { key: 'name', }; const obj2 = { name: 'Bobby Hadz', }; const result = obj1.key != undefined ? obj2[obj1.key as keyof typeof obj2] : ''; console.log(result); // ๐Ÿ‘‰๏ธ "Bobby Hadz"

use type guard to solve the-error

The code for this article is available on GitHub

We used the ternary operator to check if the obj1.key property is not nullish (null or undefined) before accessing the property in the object.

If the property is nullish, we simply return a fallback value of an empty string.

# Using an if statement to solve the error

You can also use a simple if statement that serves as a type guard.

index.ts
const obj1: { key?: string } = { key: 'name', }; const obj2 = { name: 'Bobby Hadz', }; let result = ''; if (obj1.key != undefined) { result = obj2[obj1.key as keyof typeof obj2]; } console.log(result); // ๐Ÿ‘‰๏ธ "Bobby Hadz"

The obj1.key property is guaranteed to be a string in the if block, so we can safely use it as an index type.

# Using a possibly undefined value to index an array

The error also occurs when you have a possibly undefined value with which you're trying to index an array.

index.ts
const arr = ['a', 'b', 'c']; const num: number | undefined = Math.random() > 0.5 ? 0 : undefined; // โ›”๏ธ Error: Type 'undefined' cannot be used as an index type.ts(2538) arr[num];

The num variable can store a number or an undefined value and TypeScript won't let us index the array with an undefined value.

index.ts
const arr = ['a', 'b', 'c']; const num: number | undefined = Math.random() > 0.5 ? 0 : undefined; if (num != undefined) { const result = typeof num !== undefined ? arr[num] : ''; console.log(result); // ๐Ÿ‘‰๏ธ "a" }

The num variable is guaranteed to be a number in the if block, so we can safely access the array at the specific index.

# Use a type assertion to solve the error

If none of the solutions work and you are certain the value is a number, you can use a type assertion.

index.ts
const arr = ['bobby', 'hadz', 'com']; const num: number | undefined = 1; const result = arr[num as number]; // ๐Ÿ‘ˆ๏ธ type assertion console.log(result); // ๐Ÿ‘‰๏ธ "hadz"
The code for this article is available on GitHub

Type assertions are used when we have information about the type of a value that TypeScript can't know about.

We effectively tell TypeScript that the num variable will be a number and not to worry about it.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev