typed-es
Détecter les types de sorties de vos requêtes elasticsearch automatiquement.
4 min de lecture
Pourquoi cette librairie ?
Actuellement avec la librairie node elasticsearch, lorsqu'on fait une requête search, on a des types de retour très minces.
Les
Le seul moyen d'ajouter quelques types est de tout déclarer manuellement.
Les
_source
sont de type unknown
. Il n'y a aucune sécurité sur les champs ou non d'index.Le seul moyen d'ajouter quelques types est de tout déclarer manuellement.
const result = await client.search<
{ id: number; name: string },
{ categories: { buckets: Array<{ key: string; doc_count: number }> } }
>(query);
Mais rien n'assure que les types sont correctes ni à jour par rapport à la requête..
La solution
typed-es génère automatiquement des types précis à partir de la requête Elasticsearch.
type Indexes = {
products: {
id: number;
name: string;
price: number;
category: string;
created_at: string;
},
users: {
id: number;
first_name: string;
last_name: string;
email: string;
}
};
const query = typedEs(client, {
index: "products",
_source: ["*_at", "price"],
track_total_hits: true,
rest_total_hits_as_int: true,
aggs: {
categories: { terms: { field: "category" } }
}
});
const result = await client.search(query);
const total = result.hits.total; // number
const firstHit = result.hits.hits[0]._source; // { price: number; created_at: string }
const categories = result.aggregations.categories.buckets; // Array<{ key: unknown; doc_count: number; }>
🎉 Types parfaitement inférés, sans déclaration manuelle
Fonctionnalités
Auto-completion
Comme les types sont automatiquement générés, ils sont aussi utilisés pour l'auto-complétion.
const query = typedEs(client, {
index: "p", // Ici l'IDE suggère "products"
_source: ["p"] // Une fois l'index défini sur "products", l'IDE suggère "price"
});
Note: Il est tout de même possible d'acceder à un champ qui n'existe pas directement dans la définition de l'index, exemple "name.keyword" sera accepté.
Types de sortie basés sur les champs demandés
Dérive des types exacts à partir des configurations
_source
, fields
, docvalue_fields
et aggregations
.const query = typedEs(client, {
index: "users",
_source: ["first_name", "email"],
fields: [{ field: "created_at", format: "yyyy-MM-dd" }]
});
const result = await client.search(query);
const firstHit = result.hits.hits[0];
// Type précis : {
// _source: { first_name: string; email: string },
// fields: { created_at: string[] }
// }
Support des wildcards
Détecte et infère correctement les types de sortie même lors de l'utilisation de wildcards dans
_source
, fields
et docvalue_fields
.type ProductIndex = {
products: {
created_at: string;
updated_at: string;
title: string;
}
};
const query = typedEs(client, {
index: "products",
_source: ["*_at"] // Wildcard
});
const result = await client.search(query);
const firstHit = result.hits.hits[0]._source;
// Type précis : { created_at: string; updated_at: string }
Sécurité des types de sortie
Si l'index est modifié, qu'un champ est supprimé ou que le type change, une erreur de type sera détectée.
Les options de requêtes influencent les types de sortie
const query = typedEs(client, {
index: "products",
_source: false,
fields: ["name"],
track_total_hits: true,
rest_total_hits_as_int: true
});
const result = await client.search(query);
const total = result.hits.total; // type: number, au lieu de number | estypes.SearchTotalHits | undefined
const firstHit = result.hits.hits[0];
const firstHitSource = firstHit._source; // type: never, comme `_source` est défini sur `false` il n'y aura jamais de `_source` dans la réponse
const firstHitFields = firstHit.fields; // type: { name: string[] }
Note: si
track_total_hits
était à false
, hits.total
serait de type never