Me preguntaba si es posible garantizar con Angular 12 / Typescript que todos los objetos dentro de una matriz tengan las mismas propiedades, sin declarar las propiedades explícitamente (deberían ser genéricos).
Aquí hay un ejemplo de lo que quiero lograr:
// 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'} ] Pude crear una interfaz que solo permite propiedades con tipo string , pero no pude lograr el ejemplo anterior.
export interface Data { [keys: string]: string }Actualizar (caso de uso)
Necesito este cheque en un servicio que exporta datos. Debería poder pasar una matriz de objetos, que representan filas dentro de una tabla.
Por ejemplo:
const data = [ {firstname: 'Jack', lastname: 'Sanders'}, {firstname: 'Susanna', lastname: 'Marsaglia'}, ] this.exportService.export(data);Este código generaría un archivo con una tabla como esta:
| primer nombre | apellido |
|---|---|
| Jacobo | Lijadoras |
| Susana | Marsella |
El servicio debe admitir cualquier dato pasado, ya que se usa ampliamente en toda nuestra aplicación. Pero para asegurarnos de que el servicio pueda exportar los datos a una tabla, debemos asegurarnos de que todos los objetos pasados tengan las mismas propiedades (p. ej., columnas).
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))); }Si desea una verificación de tiempo de compilación, entonces tiene sentido hacer una definición de tipo adecuada en otra respuesta. Pero eso solo funcionará si estos datos están codificados. si lo está obteniendo desde el backend, no funcionará ya que los tipos se pierden cuando el código ya está compilado, ya que javascript no tiene tipos.
Debe lograr esto mediante la interfaz como se muestra a continuación
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 errorconst data = [ {firstname: 'Jack', lastname: 'Sanders'}, {firstname: 'Susanna', lastname: 'Marsaglia'}, {firstname: 'Walter', lastname: 'Walker'} ] const dataReference : Required<typeof data[number]>[] = data