Perhaps what I’m asking to do is impossible, or I’m taking the wrong approach but is it possible to use a string to do a lookup on an imported namespace?
If I have a file: my_file.ts
and its contents are many of these:
export const MyThing: CustomType = {
propertyOne: "name",
propertyTwo: 2
}
export const AnotherThing: CustomType = {
propertyOne: "Another",
propertyTwo: 3
}
Then I have a file that is going to import all these, but needs to find and use them dynamically based on a string:
import * as allthings from "dir/folder/my_file"
function doStuff() {
let currentThing = allthings['MyThing']; // works
let name = 'MyThing';
let currentThing2 = allthings[name]; // doesnt work
}
The error I get here is:
Element implicitly has an ‘any’ type because expression of type
‘string’ can’t be used to index type ‘typeof
import("dir/folder/my_file")’. No index signature with a parameter of
type ‘string’ was found on type ‘typeof import("dir/folder/my_file")’.
Why does the literal string work but not a variable of type string?
2
Answers
I reread a similar question here: Element implicitly has an 'any' type because expression of type 'string' can't be used to index
And was finally able to get it to work by doing this:
The literal string doesn’t work because someone could reassign any string to your
let name
variable.It will work if your string is
const
. Casting it is possible:But you should just define a
const
variable which has the same effect. There’s no reason to define a variable withlet
unless you intend to change it.See this TS playground example
If you don’t know the key ahead of time, then if all the objects in
my_file
are of the same type (CustomType
), then you can safely usekeyof typeof allthings
as the typeSee TS example
For these enum like objects, you can use
satisfies Record<string, MyType>
to enforce they are all of the same type