【问题标题】:Typescript Interface, enforce the type of extra properties [duplicate]Typescript接口,强制执行额外属性的类型[重复]
【发布时间】:2017-11-05 14:48:44
【问题描述】:

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

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

那些对象总是有一个 number 类型的属性计数,其余属性是字符串

如果我使用这样的索引签名定义我的界面:

interface MyObect {
    count: number;
    [key: string]: string;
}

我得到了编译器错误:

[ts] Property 'count' of type 'number' is not assignable to string index type 'string'.

所以我必须这样定义:

interface MyObect {
    count: number;
    [key: string]: any;
}

但这个定义并不像现在这样。

有没有办法强制执行额外属性的类型?

【问题讨论】:

  • 你可以用[key: string]: string | number缩小范围

标签: typescript types interface


【解决方案1】:

我已经通过使用交叉类型实现了这样的目标:

type MyObject =
{
    count : number
} & {
    [key : string] : string
}

这对消费一个对象有效(我使用的是TypeScript 2.3.2),如下

// x : MyObject
const count : number = x.count;
const foo : string = x.foo

但正如所指出的,这个分配仍然失败

const x : MyObject = {
    count: 10,
    foo: 'bar'
}

所以这可能只在某些情况下有用。

【讨论】:

  • 感谢您的提示,我也想这样做,但使用该方法无法在不强制转换为 any 的情况下定义对象,因为该定义状态计数既是数字又是字符串女巫是不可能的。 ://
  • 我已经更新了我的答案;我看到了你的问题,我有点误解了,现在承认了。
  • 可以确定使用此方法(使用强制转换as any as MyObject)是绝对可以使用类型安全的(前提是您正确创建它们),所以如果这些只是在一个地方创建的,这可能是一个可以接受的妥协。
【解决方案2】:

在过去的两个月里,这个问题以许多微妙不同的形式出现。通常为combination of a dictionary and an array

作为替代方案,您可以使用错误抑制来保留类型的最简单定义,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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-16
    • 2019-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-13
    相关资源
    最近更新 更多