How can we correctly access a JavaScript object in TypeScript using variable evaluation with bracket notation, such as myObject[myVariable]
, when the value of the variable is unknown initially?
In the code below, an error occurs due to the uncertainty of the value in x
, making it impossible to determine if it is a key of myDictionary
:
const myDictionary = {
key1: 'String 1',
key2: 'String 2',
key3: 'String 3',
};
const possibleValuesOfX = [
'key1',
'notAKey1',
'key2',
'notAKey2',
'key3',
'notAKey3',
];
// Simulating a random potential key for myDictionary
const x =
possibleValuesOfX[Math.floor(Math.random() * possibleValuesOfX.length)];
// The following produces an error: No index signature with a parameter of type 'string' was found on type '{ key1: string; key2: string; key3: string; }'.ts(7053)
const decode = myDictionary[x];
To address this issue, the code attempts to verify whether x
is a key of myDictionary
before attempting to access it:
const myDictionary = {
key1: 'String 1',
key2: 'String 2',
key3: 'String 3',
};
const possibleValuesOfX = [
'key1',
'notAKey1',
'key2',
'notAKey2',
'key3',
'notAKey3',
];
const x =
possibleValuesOfX[Math.floor(Math.random() * possibleValuesOfX.length)];
let decode: string;
if (x in myDictionary) {
// Still results in the same error as before
decode = myDictionary[x];
}
However, this approach does not resolve the error.
The error can be resolved by defining
myDictionary: { [key: string]: string }
, but this solution disables auto-complete functionality and offers little additional benefit.
To retain auto-complete while resolving the error, the following method can be utilized:
type myDictionaryKeys = 'key1' | 'key2' | 'key3';
const myDictionary: Record<myDictionaryKeys, string> = {
key1: 'String 1',
key2: 'String 2',
key3: 'String 3',
};
const possibleValuesOfX = [
'key1',
'notAKey1',
'key2',
'notAKey2',
'key3',
'notAKey3',
];
const x =
possibleValuesOfX[Math.floor(Math.random() * possibleValuesOfX.length)];
let decode: string;
if (x in myDictionary) {
decode = myDictionary[x as myDictionaryKeys];
}
Despite resolving the error, this method may seem cumbersome and redundant, requiring the keys to be typed twice—once in the object and once in the type declaration. Is there a more elegant or efficient solution available?