TypeScript et l'Accessibilité : comment écrire du code accessible à tous

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Pourquoi l'Accessibilité ne concerne pas des "cases à cocher", mais des personnes

\n

Soyons honnêtes : quand nous entendons "accessibilité" (ou a11y), beaucoup d'entre nous imaginent des listes interminables d'exigences, des vérifications ennuyeuses et la phrase "bon, c'est pour les personnes handicapées". Mais la vérité est que l'accessibilité concerne tout le monde. Avez-vous déjà essayé de commander une pizza en marchant, en tenant votre téléphone d'une seule main ? Ou étiez-vous dans le métro avec une mauvaise connexion Internet, où le site mettait une éternité à charger ? Ce sont là des problèmes d'accessibilité.

\n

Dans cet article, nous allons parler de la façon dont TypeScript peut devenir votre meilleur ami pour créer des applications web accessibles. Pas seulement "ajouter des balises", mais construire une architecture où l'inclusivité n'est pas une fonctionnalité, mais un fondement.

\n\n

TypeScript comme bouclier contre les erreurs a11y

\n

Beaucoup pensent que TypeScript ne concerne que les types de données et la protection contre les bugs. Mais en réalité, le typage strict peut aussi sauver en matière d'accessibilité. Analysons cela avec des exemples.

\n\n

Typage des attributs ARIA

\n

L'un des problèmes les plus courants est celui des valeurs incorrectes des attributs ARIA. Avez-vous déjà écrit role="button" sur un div ? Et ensuite oublié d'ajouter tabindex ? TypeScript peut détecter cela dès la compilation.

\n
// Mauvais : aucune protection\nfunction createButton(label: string) {\n  return `<div role="button">${label}</div>`;\n}\n\n// Bon : typage des ARIA\ntype AriaRole = 'button' | 'navigation' | 'alert' | 'dialog';\n\ninterface AriaAttributes {\n  role: AriaRole;\n  'aria-label'?: string;\n  'aria-expanded'?: boolean;\n  tabIndex?: number;\n}\n\nfunction createAccessibleButton(label: string, aria: AriaAttributes) {\n  // Désormais, TypeScript vérifiera que le rôle est valide\n  return {\n    tag: 'div',\n    attrs: aria,\n    content: label\n  };\n}\n\n// Erreur ! 'btn' ne fait pas partie du type AriaRole\n// createAccessibleButton('Cliquez-moi', { role: 'btn' });
\n

Vous sentez la différence ? TypeScript ne vous laissera pas écrire accidentellement role="btutton" ou oublier un attribut obligatoire. C'est comme un assistant personnel qui murmure : "Hé, es-tu sûr que c'est accessible ?"

\n\n

Vérification stricte des états de focus

\n

Un autre point sensible est la gestion du focus. Surtout dans les SPA, où la page ne se recharge pas. TypeScript aide à créer des wrappers sécurisés.

\n
// Définir quels éléments peuvent recevoir le focus\ntype FocusableElement = HTMLInputElement | HTMLButtonElement | HTMLAnchorElement | HTMLSelectElement | HTMLTextAreaElement;\n\nfunction safelySetFocus(element: FocusableElement | null): void {\n  if (element && document.contains(element)) {\n    element.focus();\n  } else {\n    console.warn('Élément introuvable dans le DOM ou ne peut pas recevoir le focus');\n  }\n}\n\n// Utilisation\nconst modal = document.querySelector('.modal__close-btn');\nsafelySetFocus(modal as FocusableElement | null);
\n

Remarquez : nous n'appelons pas simplement .focus(), mais nous vérifions si l'élément existe et s'il peut être focalisé. Cela évite les erreurs qui pourraient laisser l'utilisateur d'un lecteur d'écran dans le vide.

\n\n

Construire une architecture avec a11y à la base

\n

Passons maintenant à des choses plus avancées. Comment faire pour que l'accessibilité soit intégrée dans l'architecture de votre projet, et non ajoutée "à la va-vite" avant la sortie ?

\n\n

Props typés pour les composants

\n

Créez une interface de base pour tous vos composants. C'est comme une constitution pour l'accessibilité.

\n
// Interface de base pour tous les composants UI\ninterface AccessibleComponentProps {\n  id?: string;\n  className?: string;\n  ariaLabel?: string;\n  ariaDescribedby?: string;\n  role?: string;\n  tabIndex?: number;\n  isDisabled?: boolean;\n  onClick?: () => void;\n  onKeyDown?: (e: React.KeyboardEvent) => void;\n}\n\n// Composant bouton spécifique\ninterface ButtonProps extends AccessibleComponentProps {\n  variant                

Blogs

Book Recommendations