malymato malymato - 3 months ago 8
TypeScript Question

Properties of exported const object map are not defined

I am trying to simulate map-like behaviour in TypeScript and also get code completion of possible values. I am limited to TypeScript 1.8.

catalog.ts

export declare type CATALOG = 'CATALOG1' | 'CATALOG2' | 'CATALOG3';
export const CATALOGS: { [catalog: string]: CATALOG } = {
CATALOG1: 'CATALOG1',
CATALOG2: 'CATALOG2',
CATALOG3: 'CATALOG3'
};


example.ts

import { CATALOGS } from './catalog';

class MyClass {
catalogs = CATALOGS;

constructor() {
CATALOGS.CATALOG1; // error
this.catalogs.CATALOG1; // error
}
}


This results in following error:


Property 'CATALOG1' does not exist on type { [catalog: string]:
"CATALOG1" | "CATALOG2" | "CATALOG3" }


Can someone elaborate?

Answer

What you're describing isn't a "map-like behaviour", with a map you'll do something like:

CATALOGS.get("CATALOG1");

And that's basically what you defined with: { [catalog: string]: CATALOG }.
You can access it like this:

let a = CATALOGS["CATALOG1"];

If you want to access it as you did, then it should be:

interface Catalogs {
    CATALOG1: CATALOG;
    CATALOG2: CATALOG;
    CATALOG3: CATALOG;
}

export const CATALOGS: Catalogs = {
    CATALOG1: 'CATALOG1',
    CATALOG2: 'CATALOG2',
    CATALOG3: 'CATALOG3'
};

let a = CATALOGS.CATALOG1;

(code in playground)