Maison > interface Web > js tutoriel > le corps du texte

L'intervention TypeScript : briser votre dépendance aux vérifications d'exécution avec Byzantium

Barbara Streisand
Libérer: 2024-10-27 06:15:29
original
797 Les gens l'ont consulté

Écoutez, nous devons parler de votre dépendance à la vérification du type. Oui, vous – celui qui dispose de 47 instances de contrôles dans votre middleware d’authentification. Le développeur qui écrit plus de cas de test que de code réel. Celui qui traite TypeScript comme si c'était juste des commentaires JSDoc fantaisistes.

L'intervention

Laissez-moi vous dresser un tableau : il est midi, vous en êtes à votre 4ème tasse de café et vous déboguez un problème de production. Les journaux montrent qu'un utilisateur a dépassé d'une manière ou d'une autre vos quinze couches de validation d'exécution. Vous avez plus de tests unitaires que Twitter n'a d'utilisateurs actifs, et pourtant, d'une manière ou d'une autre, quelqu'un a réussi à envoyer un numéro là où devrait se trouver une chaîne.

"Mais c'est impossible !" pleurez-vous en faisant défiler votre rapport de couverture de test affichant un 100 % impeccable. "J'ai vérifié ça!"

L'avez-vous pensé ? L'avez-vous vraiment ? Ou venez-vous de faire le même chèque trois fois :

  1. Une fois dans les interfaces TypeScript
  2. Encore une fois dans votre middleware de validation
  3. Et encore dans vos tests unitaires

Arrêtez de tester ce que TypeScript sait déjà

Voici une idée révolutionnaire : et si nous faisions simplement... confiance au compilateur ? Je sais, concept sauvage. Mais écoutez-moi.

interface ValidRabbit {
    username: string;
    password: string;
}
interface InvalidRabbit {
    username: number;
    password: string;
}


type ValidateRabbit<Rabbit> = Assert<
    //assert that Rabbit is of type {username, password}
    Is.Type<
        User,
        {
            username: string;
            password: string;
        }
    >,
    //custom compile time exceptions
    "Trix are for kids. Provide a username and password.",
    User
>;

// Ha! Silly Rabbit...
function checkRabbit<T>(rabbit: ValidateRabbit<T>) {
    // .... protect your trix
}

declare const rabbit1: ValidRabbit;
declare const rabbit2: InvalidRabbit;

checkRabbit(rabbit1);
checkRabbit(rabbit2);
/**        ~~~~~~~~~
 *           └───── Type Exception! "...Provide a username and password"
 */
Copier après la connexion
Copier après la connexion

"Mais qu'en est-il de la production ?"

Je vous entends maintenant : "Mais que se passe-t-il si quelqu'un envoie du JSON invalide à mon API ?"

Tout d’abord, qui vous a fait du mal ? Deuxièmement, oui, validez les limites de votre API. Mais une fois que ces données entrent dans votre domaine dactylographié, il est temps de lâcher prise. Laissez le compilateur être votre videur.

Voici ce que Byzance apporte à votre soirée sur les questions de confiance :

// Define your trust boundaries
type APIRequest<Request> = Assert<
    And<
    Is.On<Request, "body">,
    Or<Is.In<Request["method"], "POST">, Is.In<Request["method"], "PUT">>
>;,
    "Someone's being naughty with our API"
>;

// Now everything inside is type-safe
function handleRequest<R>(req: APIRequest<R>) {
    // If it compiles, it's valid
    // If it's valid, it compiles
    // This is the way
}
Copier après la connexion

L'équipe DevOps vous aimera (pour une fois)

Imaginez ceci : votre pipeline CI/CD se termine en quelques minutes au lieu d'heures. Vos journaux de production ne sont pas remplis d'erreurs de type. Votre facture AWS ne ressemble pas à un numéro de téléphone.

Comment ? Parce que Byzance déplace votre vérification de type au moment de la compilation. Pas plus :

  • Exécuter des milliers de tests unitaires qui vérifient simplement les types
  • Consommation de cycles CPU vérifiant les mêmes types encore et encore
  • Se réveiller à 3 heures du matin parce que quelqu'un a transmis undefined à une fonction qui disait clairement qu'elle voulait une chaîne
// Before: Your CPU crying for help
function validateUserMiddleware(req, res, next) {
    try {
        validateId(req.params.id)        // CPU cycle
        validateBody(req.body)           // CPU cycle
        validatePermissions(req.user)    // CPU cycle
        validateToken(req.headers.auth)  // CPU cycle
        // Your CPU is now considering a career change
        next()
    } catch (e) {
        res.status(400).json({ error: e.message })
    }
}

// After: Your CPU sending you a thank you note
type ValidRequest = Assert<
    And<
        Is.On<Request, 'params.id'>,
        Is.On<Request, 'body'>,
        Is.On<Request, 'user'>,
        Is.On<Request, 'headers.auth'>
    >,
    "Invalid request shape"
>;

function handleRequest(req: ValidRequest) {
    // Just business logic, no trust issues
}
Copier après la connexion

"Mais j'adore écrire des tests !"

The TypeScript Intervention: Breaking Your Runtime Check Addiction with Byzantium
Super! Écrivez des tests pour les choses qui nécessitent réellement des tests :

  • Logique métier
  • Points d'intégration
  • Flux de travail des utilisateurs
  • Algorithmes complexes

Vous savez ce qui n'a pas besoin d'être testé ? Si une chaîne est réellement une chaîne. Laissez TypeScript gérer cette crise existentielle.

Discussion réelle : les avantages

  1. Développement plus rapide

    • Plus besoin d'écrire la même validation de trois manières différentes
    • Détectez les erreurs au moment de la compilation, pas à 3 heures du matin
    • Passez du temps sur les fonctionnalités, pas sur le passe-partout de validation
  2. Meilleures performances

    • Zéro surcharge d'exécution pour la vérification de type
    • Tailles de bundles plus petites (pas de bibliothèques de validation)
    • CPU heureux, vie heureuse
  3. Sécurité améliorée

    • Les garanties au niveau du type ne peuvent être contournées
    • Fini les "oups, j'ai oublié de valider ça"
    • Couverture complète par défaut
  4. Rêves DevOps

    • Pipelines CI/CD plus rapides
    • Coûts d'infrastructure réduits
    • Moins d'incidents de production
    • Une équipe SRE plus heureuse (les résultats peuvent varier)

Commencer

interface ValidRabbit {
    username: string;
    password: string;
}
interface InvalidRabbit {
    username: number;
    password: string;
}


type ValidateRabbit<Rabbit> = Assert<
    //assert that Rabbit is of type {username, password}
    Is.Type<
        User,
        {
            username: string;
            password: string;
        }
    >,
    //custom compile time exceptions
    "Trix are for kids. Provide a username and password.",
    User
>;

// Ha! Silly Rabbit...
function checkRabbit<T>(rabbit: ValidateRabbit<T>) {
    // .... protect your trix
}

declare const rabbit1: ValidRabbit;
declare const rabbit2: InvalidRabbit;

checkRabbit(rabbit1);
checkRabbit(rabbit2);
/**        ~~~~~~~~~
 *           └───── Type Exception! "...Provide a username and password"
 */
Copier après la connexion
Copier après la connexion

Le choix vous appartient

Vous pouvez continuer à vivre dans la peur, en écrivant des contrôles d'exécution pour tout, en traitant TypeScript comme s'il s'agissait d'une saisie facultative pour JavaScript.

Ou vous pouvez nous rejoindre en 2024, où nous ferons confiance à notre compilateur et le laisserons faire son travail.

Rappelez-vous : chaque fois que vous écrivez une vérification de type à l'exécution, quelque part un compilateur TypeScript pleure.

Conclusion

Byzance n'est pas simplement une autre bibliothèque – c'est une intervention pour vos problèmes de confiance avec les types. Il est temps d'abandonner les contrôles d'exécution et d'adopter la puissance des garanties au moment de la compilation.

Votre CPU vous remerciera. Votre équipe DevOps vous remerciera. Vos utilisateurs vous remercieront (en ne trouvant pas de bugs liés au type).

Et surtout, vous vous remercierez à 3 heures du matin lorsque vous dormirez profondément au lieu de déboguer les erreurs de type en production.


P.S. Si vous n'êtes toujours pas convaincu, essayez de compter le nombre de vérifications de type d'exécution que vous avez dans votre base de code. Multipliez ensuite cela par votre taux horaire. C'est le temps que vous passez à ne pas faire confiance à TypeScript.

P.P.S. Aucun type n'a été blessé lors de la rédaction de ce billet de blog. Bien que plusieurs contrôles d'exécution aient été définitivement supprimés.

*P.P.P.S. Si vous souhaitez contribuer, arrêtez-vous sur mon Github et clonez le dépôt. Tout est encore frais, donc beaucoup d'opportunités de contribuer.

Documents et package disponibles sur JSR.io

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!