Typescript接口,强制执行额外属性的类型

Jos*_*one 3 types interface typescript

假设我要创建一个接口来描述这种类型的对象:

let myObj= {
    "count": 3,
    "key1": "foo",
    "key2": "bar",
    "key3": "baz"
};
Run Code Online (Sandbox Code Playgroud)

这些对象始终具有类型编号的属性计数,其余属性为字符串

如果我使用这样的索引签名定义接口:

interface MyObect {
    count: number;
    [key: string]: string;
}
Run Code Online (Sandbox Code Playgroud)

我收到了编译器错误:

[ts] Property 'count' of type 'number' is not assignable to string index type 'string'.
Run Code Online (Sandbox Code Playgroud)

所以我必须这样定义它:

interface MyObect {
    count: number;
    [key: string]: any;
}
Run Code Online (Sandbox Code Playgroud)

但是这个定义并不那么精确。

有没有一种方法可以强制执行额外属性的类型?

Fen*_*ton 6

在过去的两个月里,这个问题以多种略有不同的形式出现。通常作为字典和数组的组合

作为替代方案,您可以使用错误抑制来保留类型的最简单定义,TypeScript 编译器实际上完全能够使用该定义。

它使用错误抑制注释,这通常是一件坏事。它还需要在初始化时做一些额外的工作。其余的用法如您所料。

这是使用字典技术的具体示例的旋转。

interface MyObject {
    [key: string]: string;
    // @ts-ignore: I'm creating a Dictarray!
    count: number;
}

let myObj = { count: 0 } as MyObject;

myObj.key1 = "a string";
myObj.count = 4;

// Error, 1 is not a string - as you'd expect
myobj.key2 = 1;

myObj = {
    "count": 3,
    "key1": "foo",
    "key2": "bar",
    "key3": "baz"
} as unknown as MyObject;

const str = myObj.key1;
const num = myObj.count;
Run Code Online (Sandbox Code Playgroud)


Oly*_*Oly 5

通过使用联合类型,我已经实现了以下目标:

type MyObject =
{
    count : number
} & {
    [key : string] : string
}
Run Code Online (Sandbox Code Playgroud)

这可以使用(我正在使用TypeScript 2.3.2)消耗对象,如下所示

// x : MyObject
const count : number = x.count;
const foo : string = x.foo
Run Code Online (Sandbox Code Playgroud)

但如前所述,此分配仍然失败

const x : MyObject = {
    count: 10,
    foo: 'bar'
}
Run Code Online (Sandbox Code Playgroud)

因此这仅在某些情况下才有用。