如何使用Typescript为对象数组定义接口?

69 typescript

我有以下界面和代码.我以为我正在做正确的定义,但我收到一个错误:

interface IenumServiceGetOrderBy { id: number; label: string; key: any }[];
Run Code Online (Sandbox Code Playgroud)

和:

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

错误:

Error   190 Cannot convert '{}[]' to 'IenumServiceGetOrderBy':
    Type '{}[]' is missing property 'id' from type 'IenumServiceGetOrderBy'
Run Code Online (Sandbox Code Playgroud)

bas*_*rat 164

不需要使用索引器(因为它的类型安全性稍差).您有两种选择:

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

我个人推荐选项A(当你使用类而不是接口时更简单的迁移).

  • 第二个接口声明给出了以下 tslint 错误:“*an interface declaring no members is equal to its supertype*” (4认同)
  • 是在接口中的所有声明中添加`?`,例如.`id?:数字; label?:string; key ?: any`如果使用_less_属性而不是接口中定义的内容,那么避免出现问题的最佳方法是什么?IE浏览器.我可能不会在类型化数组设置中指定`key`. (2认同)
  • 我可以建议'key'是字符串类型吗?string[] 而不是 any。像这样:`interface EnumServiceItem { id: number; 标签:字符串;键:字符串 | 字符串[] }` (2认同)

Dou*_*las 71

您可以使用索引器定义接口:

interface EnumServiceGetOrderBy {
    [index: number]: { id: number; label: string; key: any };
}
Run Code Online (Sandbox Code Playgroud)

  • 不是"具有Typescript的对象数组的接口" (22认同)
  • 这个解决方案的问题是它不是一个`Array`接口,因此所有`Array`属性和方法,如`length`或`push`都将丢失. (9认同)
  • 是的,仅为特定项目定义接口的示例将是一种更有用的方法。拥有一系列项目但又不想方便地引用单个项目的情况是相当罕见的。使用真实数组还会在接口上公开 .length,这可能会经常使用。 (2认同)

NoN*_*ded 59

您只需扩展Array接口即可将接口定义为数组.

export interface MyInterface extends Array<MyType> { }
Run Code Online (Sandbox Code Playgroud)

有了这个,任何实现它的对象MyInterface都需要实现数组的所有函数调用,并且只能存储具有该MyType类型的对象.

  • 美丽的方案.这应该是公认的答案. (4认同)
  • 为什么不使用类型(`type MyTypeArray = Array&lt;MyType&gt;`)而不是扩展接口? (4认同)
  • 我看看这个,我希望在这个例子中也定义了“MyType”。我几乎可以使用这个答案,当然,除了我陷入困境,因为我不知道“MyType”应该是什么样子。可以用这个来更新答案吗? (2认同)

Dan*_*wer 34

额外的简单选项:

    interface simpleInt {
        id: number;
        label: string;
        key: any;
    }

    type simpleType = simpleInt[];
Run Code Online (Sandbox Code Playgroud)


Jer*_*ett 24

不使用

interface EnumServiceGetOrderBy {
    [index: number]: { id: number; label: string; key: any };
}
Run Code Online (Sandbox Code Playgroud)

您将收到所有 Arrays 属性和方法(例如 splice 等)的错误。

解决方案是创建一个接口,该接口定义另一个接口的数组(将定义对象)

例如:

interface TopCategoriesProps {
  data: Array<Type>;
}
interface Type {
  category: string;
  percentage: number;
}
Run Code Online (Sandbox Code Playgroud)


Jso*_*ody 22

所以我要加上我的两分钱:)

假设您想要一个Workplace充满 s 的类型Person。你需要这样的东西:

错误的!...作为接口


interface Workplace {
   name: string
   age: number
}[] 
// that [] doesn't work!! ;)
Run Code Online (Sandbox Code Playgroud)

这里的问题是接口用于指定类/对象形状..仅此而已。所以你可以用typewitch来代替,这样更灵活

更好 -> 使用type而不是interface


type Workplace = {
   name: string
   age: number
}[] 

// This works :D
Run Code Online (Sandbox Code Playgroud)

也许最好的是...

定义内部对象Personinterface然后由人员数组创建 - Workplace>typePerson[]


interface Person {
   name: string
   age: number
}

type Workplace = Person[]

// nice ;)

Run Code Online (Sandbox Code Playgroud)

祝你好运


Cir*_*ker 8

如果您不想创建全新类型,这里有一个内联版本:

export interface ISomeInterface extends Array<{
    [someindex: string]: number;
}> { };
Run Code Online (Sandbox Code Playgroud)


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


Blo*_*gic 8

像这样使用!

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


Eua*_*lar 5

简单的选择,没有tslint错误...

export interface MyItem {
    id: number
    name: string
}

export type MyItemList = [MyItem]
Run Code Online (Sandbox Code Playgroud)

  • 导出的MyItemList类型将是“ MyItem的一个元素数组” (3认同)
  • 可以是“导出类型MyItemList = MyItem []”吗?IMO将接口和类型别名的组合最适合这种情况,因为您在类型别名中拥有所有Array类型的方法 (3认同)