具有所有相同属性的对象数组

Array of objects which have all the same properties

我想知道,是否可以使用 Angular 12 / Typescript 来确保,数组中的所有对象都具有相同的属性,而无需显式声明属性 (应该是通用的)。

这是我想要实现的示例:

// This should compile because all objects have the same properties
const correct = [
 {firstname: 'Jack', lastname: 'Sanders'}, 
 {firstname: 'Susanna', lastname: 'Marsaglia'},
 {firstname: 'Walter', lastname: 'Walker'}
]

// This shouldn't compile because some object have different properties
const wrong = [
 {firstname: 'Aline', lastname: 'Rose', phone: 'xxx-xxx-xx-xx'},
 {firstname: 'Daniel', email: 'dan@gmail.com'},
 {firstname: 'Louisa', email: 'louisa@icloud.com'}
]

我能够创建一个只允许 string 类型的属性的接口,但我无法实现上面的示例。

export interface Data {
 [keys: string]: string
}

更新(用例)

我需要在导出数据的服务中进行此项检查。您应该能够传递一个对象数组,这些对象表示 table.

中的行

例如:

const data = [
 {firstname: 'Jack', lastname: 'Sanders'}, 
 {firstname: 'Susanna', lastname: 'Marsaglia'},
]

this.exportService.export(data);

此代码将生成一个带有 table 的文件,如下所示:

firstname lastname
Jack Sanders
Susanna Marsaglia

该服务应该支持任何传递的数据,因为它在我们的整个应用程序中被广泛使用。但是要确保服务可以将数据导出到 table,我们需要确保所有传递的对象都具有相同的属性(例如列)。

function sameKeys(input) {
  if (!input || input.length === 0) return;
  const keys = new Set(Object.keys(input[0]));

  return input.every((item) => Object.keys(item).every((key) => keys.has(key)));
}

如果你想要编译时检查,那么在另一个答案中给出了正确的类型定义是有意义的。但这只有在这些数据被硬编码时才有效。如果您从后端获取它,它将无法工作,因为当代码已经构建时类型会丢失,因为 javascript 没有类型。

你应该通过如下界面来实现

interface IStructure {
    firstname: string;
    lastname: string;
  } 

const correct: Array<IStructure> = [
 {firstname: 'Jack', lastname: 'Sanders'}, 
 {firstname: 'Susanna', lastname: 'Marsaglia'},
 {firstname: 'Walter', lastname: 'Walker'}
];

//wrong will throw error
const data = [
 {firstname: 'Jack', lastname: 'Sanders'}, 
 {firstname: 'Susanna', lastname: 'Marsaglia'},
 {firstname: 'Walter', lastname: 'Walker'}
]

const dataReference : Required<typeof data[number]>[] = data

您可以很好地使您的 exportservice 通用,即像这样

class ExportService {

  public export<T>(data: T[]) {
     console.log(data);
  }
}

或者您也可以在导出服务中使用 {[key:string]:string} 作为元素类型

class ExportService {

  public export(data: {[key:string]:string}[]) {
     console.log(data);
  }
}

这不会妨碍您正确定义 data 的类型。

const data: { firstname: string, lastname: string}[] = [
  { firstname: "john", lastname: "foo"},
  { firstname: "jim", lastname: "bar"}
];

this.exportservice.export(data);

另见 this fiddle