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]);
CodePudding user response:
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.)