简体   繁体   English

具有动态和静态键的对象的Typescript创建界面

[英]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 我正在尝试学习打字稿,涉及接口时遇到了麻烦,我有一个对象要保存一个token和一条route ,如下所示

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 '{ ... }'. TS2411:类型“字符串”的属性“令牌”不可分配给字符串索引类型“ {...}”。

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 | TS2339:类型'string |不存在属性'push' { ... }[]'. {...} []'。
Property 'push' does not exist on type 'string'. 属性“ push”在类型“ string”上不存在。

is there any other way to go about doing this? 还有其他方法可以做到这一点吗?

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 . 您可能需要的是正则表达式验证的密钥, 将来可能会出现

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]: { ... }[] | 接口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 | TS2339:类型'string |不存在属性'push' { ... }[]'. {...} []'。 Property 'push' does not exist on type 'string'. 属性“ push”在类型“ string”上不存在。

3rd Method 第三种方法

You could typecast your obj like so 您可以像这样键入obj

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 另请参阅高级类型

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM