In my opinion, a straightforward approach to support this concept is by establishing an interface that connects your type names with actual types. By doing so, you can easily retrieve them:
interface LookupType {
number: number
string: string
boolean: boolean
"number[]": number[]
person: Person
}
const type1 = "number";
let myVariable1: LookupType[typeof type1] = 12;
let type2 = "string" as const;
let myVariable2: LookupType[typeof type2] = "foo";
let type3 = 'number[]' as const
let myVariable3: LookupType[typeof type3] = [1,2,3]
This strategy functions effectively because the keys within this interface are strings, regardless of whether that string aligns with the name of the referenced type. This method proves to be simpler to maintain compared to using multiple conditional statements.
Furthermore, it offers the advantage of facilitating straightforward type checking for unsupported types
let doesntExist = 'badTypeName' as const
let badVar: LookupType[typeof doesntExist] = 123
// Property 'badTypeName' does not exist on type 'LookupType'.(2339)
Playground