Typescript接口,强制执行额外属性的类型[重复]

Posted

技术标签:

【中文标题】Typescript接口,强制执行额外属性的类型[重复]【英文标题】:Typescript Interface, enforce the type of extra properties [duplicate] 【发布时间】: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缩小范围 【参考方案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;

【讨论】:

以上是关于Typescript接口,强制执行额外属性的类型[重复]的主要内容,如果未能解决你的问题,请参考以下文章

使用泛型在接口数组中强制执行相同类型的属性

打字稿 - 强制值成为接口的属性

为啥我的 Typescript 对象允许这个额外的属性?

Typescript:至少有一个T类型属性的对象。

TYpeScript接口的使用

在 TypeScript 中,当类型是函数的参数时,有没有办法限制 Partial<T> 类型的额外/多余属性?