Last updated: Feb 28, 2024
Reading timeยท5 min
If you got the error "Type 'undefined' cannot be used as an index type", click on the second subheading.
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.
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.
To solve the error, always use the number
, string
, boolean
, Record
,
types instead.
interface Employee { name: string; // ๐๏ธ use string lowercase s } const obj: Employee = { name: 'Bobby Hadz', }; const str = 'name'; console.log(obj[str]); // ๐๏ธ "Bobby Hadz"
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
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.
Here is another example of how the error occurs.
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.
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 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
.
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.
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.
// ๐๏ธ 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.
undefined
value to index the object.To solve the error, check if the value is not undefined
before accessing the
property.
// ๐๏ธ 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"
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.
if
statement to solve the errorYou can also use a simple if
statement that serves as a
type guard.
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.
The error also occurs when you have a possibly undefined
value with which
you're trying to index an array.
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.
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.
If none of the solutions work and you are certain the value is a number
, you
can use a
type assertion.
const arr = ['bobby', 'hadz', 'com']; const num: number | undefined = 1; const result = arr[num as number]; // ๐๏ธ type assertion console.log(result); // ๐๏ธ "hadz"
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.
You can learn more about the related topics by checking out the following tutorials: