如何为对象数组定义接口?
Posted
技术标签:
【中文标题】如何为对象数组定义接口?【英文标题】:How can I define an interface for an array of objects? 【发布时间】:2014-10-17 14:52:32 【问题描述】:我有以下界面和代码。我以为我的定义是正确的,但我得到了一个错误:
interface IenumServiceGetOrderBy id: number; label: string; key: any [];
和:
getOrderBy = (entity): IenumServiceGetOrderBy =>
var result: IenumServiceGetOrderBy;
switch (entity)
case "content":
result =
[
id: 0, label: 'CId', key: 'contentId' ,
id: 1, label: 'Modified By', key: 'modifiedBy' ,
id: 2, label: 'Modified Date', key: 'modified' ,
id: 3, label: 'Status', key: 'contentStatusId' ,
id: 4, label: 'Status > Type', key: ['contentStatusId', 'contentTypeId'] ,
id: 5, label: 'Title', key: 'title' ,
id: 6, label: 'Type', key: 'contentTypeId' ,
id: 7, label: 'Type > Status', key: ['contentTypeId', 'contentStatusId']
];
break;
return result;
;
错误:
Error 190 Cannot convert '[]' to 'IenumServiceGetOrderBy':
Type '[]' is missing property 'id' from type 'IenumServiceGetOrderBy'
【问题讨论】:
【参考方案1】:您可以使用indexer 定义接口:
interface EnumServiceGetOrderBy
[index: number]: id: number; label: string; key: any ;
【讨论】:
不是真正的“Typescript 对象数组的接口” 是的,您仅为特定项目定义接口的示例将是一种更有用的方法。拥有一系列项目但又不想方便地引用单个项目的情况非常罕见。使用真实数组也会在接口上暴露 .length,这可能会经常使用。 如何定义类来实现这个接口? 这个解决方案的问题是这不是Array
接口,因此所有Array
属性和方法如length
或push
都会丢失。
有了这个你会在使用数组函数时出错,看这个 - ***.com/q/50215823/9640177【参考方案2】:
您不需要 使用索引器(因为它的类型安全性稍差)。你有两个选择:
interface EnumServiceItem
id: number; label: string; key: any
interface EnumServiceItems extends Array<EnumServiceItem>
// Option A
var result: EnumServiceItem[] = [
id: 0, label: 'CId', key: 'contentId' ,
id: 1, label: 'Modified By', key: 'modifiedBy' ,
id: 2, label: 'Modified Date', key: 'modified' ,
id: 3, label: 'Status', key: 'contentStatusId' ,
id: 4, label: 'Status > Type', key: ['contentStatusId', 'contentTypeId'] ,
id: 5, label: 'Title', key: 'title' ,
id: 6, label: 'Type', key: 'contentTypeId' ,
id: 7, label: 'Type > Status', key: ['contentTypeId', 'contentStatusId']
];
// Option B
var result: EnumServiceItems = [
id: 0, label: 'CId', key: 'contentId' ,
id: 1, label: 'Modified By', key: 'modifiedBy' ,
id: 2, label: 'Modified Date', key: 'modified' ,
id: 3, label: 'Status', key: 'contentStatusId' ,
id: 4, label: 'Status > Type', key: ['contentStatusId', 'contentTypeId'] ,
id: 5, label: 'Title', key: 'title' ,
id: 6, label: 'Type', key: 'contentTypeId' ,
id: 7, label: 'Type > Status', key: ['contentTypeId', 'contentStatusId']
]
我个人推荐选项 A(当您使用类而不是接口时迁移更简单)。
【讨论】:
正在将?
添加到界面中的所有声明中,例如。 id?: number; label?: string; key?: any
如果您使用 less 属性而不是接口中定义的属性,那么避免转换问题的最佳方法是什么? IE。我可能不会在类型化数组设置中指定key
。
选项 B 很有用,因为它允许您在编写更高级别的接口时使用该接口。
天哪,这困扰了我这么久,谢谢!
第二个接口声明给出以下 tslint 错误:“一个声明没有成员的接口等同于它的超类型”
我可以建议'key'是字符串类型吗?字符串 [] 而不是任何。像这样:interface EnumServiceItem id: number; label: string; key: string | string[]
【参考方案3】:
您可以通过简单地扩展 Array 接口将接口定义为数组。
export interface MyInterface extends Array<MyType>
这样,任何实现MyInterface
的对象都需要实现数组的所有函数调用,并且只能存储MyType
类型的对象。
【讨论】:
漂亮的解决方案。这应该是公认的答案。 为什么不使用类型 (type MyTypeArray = Array<MyType>
) 而不是扩展接口?
OP 要求提供接口,我假设它是用其他属性和方法扩展的,你不能用类型来做到这一点,而且在一般可用性方面,类型比接口更受限制
我看了这个,我希望在这个例子中也定义了MyType
。我几乎可以使用这个答案,当然,除了我卡住了,因为我不知道MyType
应该是什么样子。是否可以用它来更新答案?
最好的解决方案应该是公认的答案【参考方案4】:
没有 tslint 错误的简单选项 ...
export interface MyItem
id: number
name: string
export type MyItemList = [MyItem]
【讨论】:
导出的MyItemList
类型将是“MyItem
的单元素数组”
可能是export type MyItemList = MyItem[]
?。 IMO 接口和类型别名的组合最适合这种情况,因为您的类型别名中包含 Array 类型的所有方法【参考方案5】:
如果你不想创建一个全新的类型,这里有一个内联版本:
export interface ISomeInterface extends Array<
[someindex: string]: number;
> ;
【讨论】:
我喜欢这个选项。【参考方案6】:你也可以这样做。
interface IenumServiceGetOrderBy
id: number;
label: string;
key: any;
// notice i am not using the []
var oneResult: IenumServiceGetOrderBy = id: 0, label: 'CId', key: 'contentId';
//notice i am using []
// it is read like "array of IenumServiceGetOrderBy"
var ArrayOfResult: IenumServiceGetOrderBy[] =
[
id: 0, label: 'CId', key: 'contentId' ,
id: 1, label: 'Modified By', key: 'modifiedBy' ,
id: 2, label: 'Modified Date', key: 'modified' ,
id: 3, label: 'Status', key: 'contentStatusId' ,
id: 4, label: 'Status > Type', key: ['contentStatusId', 'contentTypeId'] ,
id: 5, label: 'Title', key: 'title' ,
id: 6, label: 'Type', key: 'contentTypeId' ,
id: 7, label: 'Type > Status', key: ['contentTypeId', 'contentStatusId']
];
【讨论】:
【参考方案7】:其他简单的选项:
interface simpleInt
id: number;
label: string;
key: any;
type simpleType = simpleInt[];
【讨论】:
非常好,简单,优雅。【参考方案8】:在 Angular 中,使用“扩展”来定义对象“数组”的接口。
使用索引器会报错,因为它不是数组接口,因此不包含属性和方法。
例如
错误 TS2339:类型“ISelectOptions2”上不存在属性“find”。
// good
export interface ISelectOptions1 extends Array<ISelectOption>
// bad
export interface ISelectOptions2
[index: number]: ISelectOption;
interface ISelectOption
prop1: string;
prop2?: boolean;
【讨论】:
如果 linter 不允许空接口,此方法将导致“声明无成员的接口等同于其超类型”。 这个答案非常接近它帮助我解决了我的问题!对于要在另一个接口中为其创建数组的初始对象,键入“interface ISelectOptions name1 : type; name2: type; 然后在 BIG 接口中,当你到达想要成为数组的键时那个类型,keyZ: ISelectOptions[]; 然后当你创建 JSON 时, myVar : BIG = key1: val1, key2: val2, ..., keyZ: [name1 : valA, name2: valB, name1 : valC, name2 : valD] 像冠军一样工作!(虽然不需要扩展 Array 类)谢谢!【参考方案9】:编程很简单。使用简单的用例:
interface IenumServiceGetOrderBy id: number; label: string; key: any
// OR
interface IenumServiceGetOrderBy id: number; label: string; key: string | string[]
// use interface like
const result: IenumServiceGetOrderBy[] =
[
id: 0, label: 'CId', key: 'contentId' ,
id: 1, label: 'Modified By', key: 'modifiedBy' ,
id: 4, label: 'Status > Type', key: ['contentStatusId', 'contentTypeId']
];
【讨论】:
【参考方案10】:不要使用
interface EnumServiceGetOrderBy
[index: number]: id: number; label: string; key: any ;
您将收到所有 Arrays 属性和方法(例如 splice 等)的错误。
解决方案是创建一个接口,该接口定义另一个接口的数组(将定义对象)
例如:
interface TopCategoriesProps
data: Array<Type>;
interface Type
category: string;
percentage: number;
【讨论】:
【参考方案11】:这是一种适合您的示例的解决方案:
interface IenumServiceGetOrderByAttributes
id: number;
label: string;
key: any
interface IenumServiceGetOrderBy extends Array<IenumServiceGetOrderByAttributes>
let result: IenumServiceGetOrderBy;
通过此解决方案,您可以使用 Array 的所有属性和方法(例如:
length, push(), pop(), splice()
...)
【讨论】:
【参考方案12】:这样使用!
interface Iinput
label: string
placeholder: string
register: any
type?: string
required: boolean
// This is how it can be done
const inputs: Array<Iinput> = [
label: "Title",
placeholder: "Bought something",
register: register,
required: true,
,
]
【讨论】:
【参考方案13】:我会使用以下结构:
interface arrayOfObjects extends Array<>
然后更容易定义:
let myArrayOfObjects: arrayOfObjects = [
id: 0, label: "CId", key: "contentId" ,
id: 1, label: "Modified By", key: "modifiedBy" ,
id: 2, label: "Modified Date", key: "modified" ,
id: 3, label: "Status", key: "contentStatusId" ,
id: 4, label: "Status > Type", key: ["contentStatusId", "contentTypeId"] ,
id: 5, label: "Title", key: "title" ,
id: 6, label: "Type", key: "contentTypeId" ,
id: 7, label: "Type > Status", key: ["contentTypeId", "contentStatusId"] ,
];
【讨论】:
以上是关于如何为对象数组定义接口?的主要内容,如果未能解决你的问题,请参考以下文章