circumspect
est un ensemble de fonctions pour rendre votre code TypeScript/JavaScript plus sûr. Ces fonctions incluent invariant
, warning
, assertNever
, etc.
Il existe de nombreuses fonctions utiles qui peuvent rendre votre code plus sûr, telles que invariant
et assertNever
. Beaucoup de ces fonctions sont disponibles sous forme de packages npm distincts (par exemple, invariant
). Mais installer un nouveau package (et la plupart du temps son homologue @types
également) pour chaque fonction n'est pas très pratique. De plus, ces packages exportent généralement leurs fonctions en tant qu'exportations par défaut, ce qui empêche l'importation automatique de VSCode de fonctionner correctement avec eux.
Cette bibliothèque unifie les fonctions qui rendent votre code plus sûr en un seul endroit. circumspect
est une dépendance unique qui les a tous. Et l'importation automatique VSCode fonctionne comme prévu car toutes les fonctions fournies par circumspect
sont nommées exportations.
De plus, circumspect
est écrit à 100 % en TypeScript, donc chaque fonction est correctement saisie par défaut. Il n’est donc pas nécessaire d’installer des packages @types
distincts.
Utiliser du fil :
yarn add circumspect
Utilisation de npm :
npm install circumspect
invariant
warning
assertNever
nonNull
invariant
invariant ( value : unknown , message ?: string ) : asserts value
value: unknown
est la valeur dont nous voulons nous assurer qu'elle est véridique.
message?: string
est un message d'erreur facultatif qui sera inclus dans l'erreur générée lorsque la value
transmise est fausse. Ce message d'erreur personnalisé s'affiche uniquement en développement. En production, une erreur générique est affichée à la place ( 'Invariant violation'
) et le paramètre message
est ignoré.
asserts value
, ce qui signifie que la fonction restreint simplement le type de value
pour qu'il soit véridique et ne renvoie rien. invariant
garantit que la value
spécifiée est véridique. Si ce n'est pas le cas, il renvoie une erreur contenant le message
spécifié (en développement uniquement). Cette fonction restreint correctement le type de value
en excluant toutes les valeurs fausses (par exemple, null
et undefined
).
invariant
doit être utilisé chaque fois que nous avons une valeur qui pourrait potentiellement être fausse, mais nous sommes convaincus que dans une circonstance particulière, la valeur doit être véridique. Autrement dit, le fait que la valeur soit véridique est un invariant, et s'il arrive que la valeur soit fausse, l'invariant a été violé et une erreur doit donc être générée.
Étant donné que l'argument message
est complètement ignoré en production, vous souhaiterez peut-être le supprimer complètement de votre code dans les versions de production. Pour voir comment procéder, consultez la section Optimisations.
declare const user : User | null | undefined ;
invariant ( user , 'The user is missing!' ) ;
user ; // If we get here, the type is narrowed to `User`
Dans cet exemple, l'objet user
peut potentiellement être null
ou undefined
(c'est-à-dire faux). Si tel est le cas, nous avons une violation invariante et la fonction invariant
sera lancée. Sinon, il revient simplement et nous savons que user
pointe réellement vers un objet utilisateur.
warning
warning ( value : unknown , message : string ) : void
value: unknown
est la valeur que nous voulons vérifier. S'il est faux, un avertissement est envoyé à la console.
message: string
est le message d'avertissement qui sera écrit sur la console.
void
la fonction ne renvoie rien. warning
émet un avertissement à la console avec le message
donné si la value
spécifiée est fausse. L'avertissement n'est émis qu'en cours de développement. En production, cette fonction ne fait rien.
Il doit être utilisé chaque fois que nous souhaitons émettre un avertissement réservé au développement si une valeur est fausse, ce qui devrait aider les développeurs à résoudre les problèmes non critiques signalés dans le message d'avertissement.
Étant donné que warning
ne fait rien en production, vous souhaiterez peut-être supprimer complètement les appels à cette fonction de votre code dans les versions de production. Pour voir comment procéder, consultez la section Optimisations.
declare const mode : 'auto' | 'default' | 'slow' | 'fast' ;
warning (
mode !== 'auto' ,
'Mode "auto" has been deprecated. Please use "default" instead.' ,
) ;
Dans cet exemple, nous souhaitons émettre un avertissement de dépréciation si le mode
est 'auto'
. Pour ce faire, nous devons transmettre une valeur fausse, c'est pourquoi nous transmettons mode !== 'auto'
, qui n'est fausse que lorsque le mode
est 'auto'
.
Dans certains cas, il est logique de transmettre directement false
. Par exemple:
declare const languages : Language [ ] ;
declare const defaultLanguage : Language ;
declare const langName : string ;
let lang = languages . find ( ( { name } ) => name === langName ) ;
if ( ! lang ) {
warning (
false ,
`Language with name " ${ langName } " not found. Falling back to the default language.` ,
) ;
lang = defaultLanguage ;
}
assertNever
assertNever ( value : never ) : never
value: never
affichée une fois que toutes les variantes possibles du type d'union ont été épuisées. never
, ce qui signifie que la fonction ne revient jamais ; cela génère simplement une erreur si jamais il est réellement appelé. assertNever
doit être utilisé pour garantir que toutes les variantes d'un type d'union ont été épuisées.
Si toutes les variantes d'union de value
ont été épuisées, il n'y a pas d'erreur du compilateur lors de l'appel assertNever
avec value
, puisque value
est considérée comme étant de type never
à ce stade, et au moment de l'exécution, nous n'atteignons jamais le point d'appeler assertNever
, ce qui signifie que aucune erreur ne sera générée.
Cependant, si toutes les variantes d'union n'ont pas été épuisées, alors nous appelons assertNever
avec autre chose que never
et il y aura donc une erreur du compilateur disant quelque chose comme
Argument of type 'x' is not assignable to parameter of type 'never'.
que nous pouvons corriger en gérant les variantes manquantes. Vous pouvez en savoir plus sur la vérification de l'exhaustivité des unions et assertNever
dans la documentation TypeScript.
declare const state : 'loading' | 'done' | 'error' ;
switch ( state ) {
case 'loading' :
return < Loading / > ;
case 'done' :
return < Done / > ;
case 'error' :
return < Error / > ;
}
Dans cet exemple, nous traitons tous les états possibles dans l'instruction switch
: 'loading'
, 'done'
et 'error'
.
Cependant, que se passerait-il si à l'avenir nous ajoutions un autre état, tel que 'pending'
?
Le fait que l'instruction switch
ne gère pas 'pending'
ne serait pas détecté.
La solution est d’avoir un cas default
dans lequel nous affirmons que tous les états possibles ont été traités.
switch ( state ) {
...
default :
return assertNever ( state ) ;
}
Ainsi, lorsque toutes les variantes d’état sont gérées, nous n’obtenons aucune erreur de compilation. Cependant, lorsque nous ajoutons le nouvel état 'pending'
, nous obtiendrons une erreur du compilateur indiquant :
Argument of type 'string' is not assignable to parameter of type 'never'.
Nous pouvons corriger cette erreur en gérant l'état 'pending'
à l'intérieur du switch
.
Comme vous pouvez le voir sur cet exemple, assertNever
est particulièrement utile dans les instructions switch
où nous voulons nous assurer d'avoir traité tous les cas possibles à tout moment.
nonNull
nonNull < T > ( value : T | null | undefined ) : value is T
value: T | null | undefined
est la valeur dont nous voulons vérifier qu'elle n'est pas null
ou undefined
. value is T
ce qui signifie que la fonction renvoie un booléen indiquant si la valeur transmise n'est ni null
ni undefined
. Cela restreint le type de value
à T
(c'est-à-dire exclut null
et undefined
) lorsque true
est renvoyé. nonNull
est une fonction de prédicat qui vérifie si la valeur spécifiée est non nulle, c'est-à-dire ni null
ni undefined
. Après avoir appelé la fonction, le type de value
est correctement restreint selon que true
ou false
a été renvoyé.
nonNull
doit être utilisé chaque fois que nous avons une valeur qui pourrait potentiellement être null
, undefined
ou les deux et que nous voulons vérifier cela et que son type soit correctement restreint.
Le nom de cette fonction provient du type d'utilitaire NonNullable
, qui exclut null
et undefined
d'un type.
declare const names : ( string | null ) [ ] ;
const nonNullNames = names . filter ( nonNull ) ;
// nonNullNames has type 'string[]'
Dans cet exemple, nous avons un tableau de noms qui peuvent également inclure des éléments null
. Nous filtrons le tableau pour tous les éléments non nuls et récupérons un string[]
.
Si nous utilisions à la place names.filter(x => x !== null)
, nous récupérerions des éléments non nuls, mais le type serait toujours (string | null)[]
puisque TypeScript voit la fonction que nous transmettons au filter
comme simplement renvoyer un boolean
et donc aucun rétrécissement de type ne se produit.
Nous vous recommandons d'utiliser babel-plugin-dev-expression
pour supprimer l'argument message
passé à invariant
et pour supprimer complètement les appels à warning
en production.
Fondamentalement, en production, babel-plugin-dev-expression
remplace
invariant ( value , 'Value is falsy!' ) ;
avec
if ( ! value ) {
invariant ( false ) ;
}
donc l'argument message
est supprimé. Il supprime également complètement les appels à warning
. Donc, des lignes comme celle-ci
warning ( value , 'Value is falsy!' ) ;
sont supprimés.
Les demandes de tirage sont les bienvenues. Si vous avez l'intention d'introduire un changement majeur, veuillez d'abord ouvrir un numéro connexe dans lequel nous pourrons discuter de ce que vous souhaitez changer.
Veuillez vous assurer de mettre à jour les tests et le README le cas échéant.
MIT