12

I'm trying to learn typescript and I've hit a road bump when it comes to the interfaces, I have a object that I want to save one token and one route in as follows

const obj = {
  token: 'thisismytoken',
  '/path/to/somewhere': [{ ... }]
}

The problem I'm having here is: how do I generate the interface for this object?

I've tried:

interface iObject {
  token: string;
  [key: string]: { ... }[]
}

but this generates the error:

TS2411: Property 'token' of type 'string' is not assignable to string index type '{ ... }'.

same thing happens when I try something like:

interface iRoute {
  val1: number;
  val2: string;
}

interface iObject extends iRoute {
  token: string;
}

When I try something like:

interface iObject {
  [key: string]: { ... }[] | string;
}

I get the following error when I try to add data to the route variable:

TS2339: Property 'push' does not exist on type 'string | { ... }[]'.
Property 'push' does not exist on type 'string'.

is there any other way to go about doing this?

1

2 Answers 2

5

You could do something like this. You are trying to create a dictionary so this might help.

To have a clean code

1st Method

interface IDictionary<T> {
    [key: string]: T;
}

interface iObject {
    token: string;
    route: IDictionary<any[]>;
}

//Use it like this
var obj: iObject = {
            token: "thisismytoken",
            route: {
                "/path/to/somewhere": [{
                    pathName: 'somewhere'
                }]
            }
        };

Here is a working typescript playground

2nd Method based on your last try

When I try something like:

interface iObject { [key: string]: { ... }[] | string; }

    interface IDictionary<T> {
        [key: string]: T;
    }

    var obj: IDictionary<any> = {
            token: "asdf123",
            "path/to/somewhere": [{
                data: 'something'
            }]
        };

TS2339: Property 'push' does not exist on type 'string | { ... }[]'. Property 'push' does not exist on type 'string'.

3rd Method

You could typecast your obj like so

interface iObject {
  [key: string]: Array<object> | string;
}

self.obj = {
            token: self.tokenVal
        };
        self.obj[self.route] = [{ "routeName": self.routeName }];

        (<Array<object>>self.obj[self.route]).push({
            "zip": "123456"
        });

Also refer to Advanced Types

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

5 Comments

Hi, thanks, I am however already to deep into the array for my liking, I would like to not add an extra layer specially if the only reason for doing so is to get the interface working
@Touchpad You could only use the IDictionary interface as it is generic. You don't need to change anything. Arrays will work too as the type will be any.
@Touchpad I have updated my answer to include another approach.
1st Method would result in an extra layer (route). as for the second method, I would really like to avoid the use of any if possible
@Touchpad I got your point check my latest update. I hope it helps you.
4

You can use intersection types for this:

type iObject = {
    token: string
} & {
    [key: string]: { ... }[]
}

But note that the indexed type doesn't limit you to one property. What you probably would need are regex validated keys, which might come in the future.

4 Comments

Not working when assigning the type: femto.pw/hej8
This is incorrect. Please, don't suggest a solution that doesn't work at all
I'm not sure what the complaints are, this worked for me. It's ugly to mix static and dynamic keys, but I'm stuck with someone else's schema. In my case, the dynamic keys had a pattern, and since I'm using TS 4.1+, I was able to be a bit more specific: type Meeting = {[name: `Sensor_${number}`]: SensorMeetingRecord} & {id: number; topic: string; startTime: number; ... }
In @RobertRendell's case, the keys don't overlap. But, no, the above doesn't work because the [key: string] overlaps the token field and requires it to match as well. With that said, I have some incredibly elaborate case that uses it with interfaces and classes, and it works well.. literally no clue how. Maybe it's a bug?

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.