【问题标题】:Typescript creating interface for object with both dynamic and static keysTypescript为具有动态和静态键的对象创建接口
【发布时间】:2018-07-03 10:18:55
【问题描述】:

我正在尝试学习 typescript,但在接口方面遇到了困难,我有一个对象,我想保存一个 token 和一个 route,如下所示

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

我遇到的问题是:如何为这个对象生成接口?

我试过了:

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

但这会产生错误:

TS2411:“字符串”类型的属性“令牌”不可分配给字符串索引类型“{ ... }”。

当我尝试类似的事情时会发生同样的事情:

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

interface iObject extends iRoute {
  token: string;
}

当我尝试类似:

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

当我尝试向路由变量添加数据时出现以下错误:

TS2339:“字符串 | 类型”上不存在属性“推送” { ... }[]'。
类型“字符串”上不存在属性“推送”。

还有其他方法可以做到这一点吗?

【问题讨论】:

标签: typescript interface typescript-typings


【解决方案1】:

你可以做这样的事情。您正在尝试创建字典,因此这可能会有所帮助。

要有一个干净的代码

第一种方法

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'
                }]
            }
        };

这是working typescript playground

第二种方法基于您上次的尝试

当我尝试类似:

接口 iObject { [key: string]: { ... }[] |细绳; }

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

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

TS2339:“字符串”类型上不存在属性“推送”| { ... }[]'。 类型“字符串”上不存在属性“推送”。

第三种方法

你可以像这样对你的 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"
        });

另请参阅Advanced Types

【讨论】:

  • 嗨,谢谢,不过我已经根据自己的喜好深入到数组中,如果这样做的唯一原因是让界面正常工作,我不想特别添加额外的层跨度>
  • @Touchpad 您只能使用 IDictionary 接口,因为它是通用的。你不需要改变任何东西。数组也可以工作,因为类型可以是任何类型。
  • @Touchpad 我已经更新了我的答案以包含另一种方法。
  • 第一种方法会产生一个额外的层 (route)。至于第二种方法,如果可能的话,我真的很想避免使用any
  • @Touchpad 我明白你的意思了,看看我的最新更新。希望对你有帮助。
【解决方案2】:

您可以为此使用交集类型:

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

但请注意,索引类型不会将您限制为一个属性。您可能需要的是经过正则表达式验证的密钥,might come in the future

【讨论】:

  • 分配类型时不起作用:femto.pw/hej8
  • 这是不正确的。请不要提出根本不起作用的解决方案
猜你喜欢
  • 2021-06-08
  • 1970-01-01
  • 2020-08-22
  • 1970-01-01
  • 1970-01-01
  • 2017-01-08
  • 2021-09-16
  • 1970-01-01
相关资源
最近更新 更多