Typescript 为具有动态和静态键的对象创建接口

Tou*_*pad 12 interface typescript typescript-typings

我正在尝试学习打字稿,但在界面方面遇到了障碍,我有一个对象,我想将其一一保存,token如下route所示

const obj = {
  token: 'thisismytoken',
  '/path/to/somewhere': [{ ... }]
}
Run Code Online (Sandbox Code Playgroud)

我在这里遇到的问题是:如何生成该对象的接口?

我试过了:

interface iObject {
  token: string;
  [key: string]: { ... }[]
}
Run Code Online (Sandbox Code Playgroud)

但这会产生错误:

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

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

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

interface iObject extends iRoute {
  token: string;
}
Run Code Online (Sandbox Code Playgroud)

当我尝试类似的事情时:

interface iObject {
  [key: string]: { ... }[] | string;
}
Run Code Online (Sandbox Code Playgroud)

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

TS2339:类型“string | ”上不存在属性“push” { ... }[]'。
类型“string”上不存在属性“push”。

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

Tao*_*Tao 5

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

type iObject = {
    token: string
} & {
    [key: string]: { ... }[]
}
Run Code Online (Sandbox Code Playgroud)

但请注意,索引类型并不限制您只能使用一种属性。您可能需要的是经过正则表达式验证的密钥,这可能会在将来出现

  • 这是不正确的。请不要提出根本不起作用的解决方案 (3认同)

Hey*_*eep 4

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

拥有干净的代码

第一种方法

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'
                }]
            }
        };
Run Code Online (Sandbox Code Playgroud)

这是一个正在运行的打字稿游乐场

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

当我尝试类似的事情时:

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

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

    var obj: IDictionary<any> = {
            token: "asdf123",
            "path/to/somewhere": [{
                data: 'something'
            }]
        };
Run Code Online (Sandbox Code Playgroud)

TS2339:类型“string | ”上不存在属性“push” { ... }[]'。类型“string”上不存在属性“push”。

第三种方法

你可以像这样对你的 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"
        });
Run Code Online (Sandbox Code Playgroud)

另请参阅高级类型