2

I receive some reference data in this form from my server:

interface Status {
    id: number;
    code: string;
    description: string;
}

In JavaScript, I would convert it into something that I could reference in enum style by doing this:

let as = resp.data as Status[];
let statuses: any = {};
statuses.descriptions = {};

for (let a of as) {
   statuses[a.code] = a.id;
   statuses.descriptions[a.id] = a.description;
}

which would allow me to write:

statuses.ONE_STATUS

and I'd get back the id of the record. This made it easy to reference the records by their 'code' (ie. symbolically) rather than by assuming the ID of the record in the database when setting foreign keys, etc.

Now I'm converting this to TypeScript and can't figure out how to write this code and not use the any type for statuses.

Any suggestions?

--- Update ---

Seems I can't get exactly what I want, but I can do this:

interface Status {
    id: number;
    description: string;
}

interface Statuses {
    [statusIndex: string]: Status;
}

which I can then populate with this:

let statuses: Statuses;

for (let a of as) {
    statuses[a.code].id = a.id;
    statuses[a.code].description = a.description;
}

and that doesn't do exactly what I want, but it does do:

statuses.ONE_STATUS.id or statuses["ONE_STATUS"].id

to get the id, and

statuses.ONE_STATUS.description

to get the description.

The dictionary approach is what I would have done in C#, so I feel right at home :)

2 Answers 2

1

The simplest approach will be the following:

interface Descriptions {
    [index: number]: string;
}

interface Statuses {
    descriptions: Descriptions;
    [index: string]: number;
}

let statuses: Statuses = {descriptions: {}}

This way you'll be able to query both statuses and statuses.descriptions with arbitrary string and number keys correspondingly. I'd try to improve this a bit using symbols, but it seems that TS doesn't support them as keys yet.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for that. I didn't know about Indexable Types until this. However, that doesn't work. I get: Property 'description' of type 'Descriptions' is not assignable to string index type 'number'. Which makes sense after reading the Typescript docs, which says you can't mix something of type Descriptions and something of type number in the same indexable thing. But I did implement something better (see above).
0

This made it easy to reference the records by their 'code' (ie. symbolically) rather than by assuming the ID of the record in the database when setting foreign keys, etc.

If you want to be able to write statuses.ONE_STATUS then statuses must be an enum. e.g.

enum statuses {
  ONE_STATUS;
}

1 Comment

I'm sorry, but do you understand the question? In your variant, statuses.ONE_STATUS is a compile-time constant, even if the enum itself isn't declared as const. That's not the same as "id of the record" OP is asking for.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.