Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript creating interface for object with both dynamic and static keys

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?

like image 474
Touchpad Avatar asked Mar 08 '23 02:03

Touchpad


1 Answers

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

like image 75
Hey24sheep Avatar answered Mar 10 '23 11:03

Hey24sheep