In the below example I get the type error on obj[oid]
Element implicitly has an ‘any’ type because expression of type ‘2’
can’t be used to index type ‘{}’.
I imagine that I somehow have to specify that all the elements in the obj object are any, as I don’t know the objects structure before hand?
import * as TOML from '@iarna/toml';
import * as fs from 'fs';
function readToml(filename: string): object {
return TOML.parse(fs.readFileSync(filename, 'utf-8'));
}
const obj = readToml('./output/obj.toml');
const oid = 2;
const offerId = 1;
console.log(obj[oid].offers[offerId]);
>Solution :
Yes. When you don’t know the structure of an object at compile-time, you probably want to reach for the Record utility type. For instance, in this case you might make the return type of the readToml function Record<string, any>, which says "An object whose properties have string keys and any values."
function readToml(filename: string): Record<string, any> {
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^^^^^^^
return TOML.parse(fs.readFileSync(filename, 'utf-8'));
}
If you don’t even know for sure it’ll be an object, you’d use any, or if you know it will be just one of several types, you’d use a union of those types. For example, if you knew that you’d get back either a Record<string, any> or a string (but not, say, a number or boolean), you could use the type Record<string, any> | string to express that at the type level. (That’s not likely in this case, it’s just meant as an example for other situations.)