ComparaisonComparaisons

void vs never

void signifie qu’une fonction ne renvoie pas de valeur utile, tandis que never signifie qu’une fonction ne revient jamais : elle lève une erreur ou tourne indéfiniment.

Sur cette page

Comparaison point par point

#
  • La fonction se termine normalement

    void
    Oui
    never
    Non, elle lève une erreur ou tourne indéfiniment
  • Résultat réel à l’exécution

    void
    undefined
    never
    Aucun, la fonction ne revient jamais
  • Peut affecter une valeur de ce type à une variable

    void
    Oui, seulement undefined
    never
    Non, aucune valeur ne correspond
  • Vérification d’exhaustivité d’une union

    void
    Ne l’exprime pas
    never
    Oui, dans la branche default
  • Type de fonction de rappel (callback)

    void
    Souple : accepte aussi une fonction qui renvoie quelque chose
    never
    Rarement utilisé dans ce rôle
  • Usage typique

    void
    Fonctions sans résultat utile, gestion d’événements
    never
    Fonctions qui lèvent une erreur, assertNever, boucles sans fin

Exemple

#
TypeScript
function logProgress(done: number, total: number): void {
  console.log(`Progression : ${Math.round((done / total) * 100)}%`)
}

function fail(message: string): never {
  throw new Error(message)
}

const result = logProgress(3, 4)
console.log(result)

try {
  fail('une erreur est survenue')
} catch (error) {
  console.log((error as Error).message)
}
Résultat
Progression : 75%
undefined
une erreur est survenue

Définition et utilisation

#

Les deux types décrivent le plus souvent la valeur renvoyée par une fonction et s’utilisent là où une valeur ordinaire n’a pas de sens. Aucun des deux ne permet d’effectuer ensuite une opération sensée sur le résultat.

La différence est fondamentale. Une fonction de type void se termine normalement, elle ne renvoie simplement rien d’utile, et en pratique son résultat est undefined. Une fonction de type never ne revient jamais à l’endroit de l’appel : soit elle lève une exception, soit elle tourne dans une boucle infinie. never apparaît aussi comme le type de valeurs qui ne peuvent pas se produire, par ex. dans la branche default après avoir traité toutes les variantes d’une union, ce que void n’exprime jamais.

Ajoutez le type void aux fonctions qui exécutent un effet, par ex. qui journalisent, enregistrent ou modifient un état, et dont personne ne devrait utiliser le résultat. Réservez le type never aux fonctions utilitaires qui lèvent toujours une erreur, et à la vérification d’exhaustivité d’une union dans un switch. N’utilisez jamais never comme type d’une variable à laquelle vous voulez affecter quelque chose, car aucune valeur ne lui correspond.

Syntaxe

#
Syntaxe
function name(): void { … }
function fail(): never { throw new Error() }

Plus d’exemples

#
never pour la vérification d’exhaustivité d’une union
TypeScript
type Command = { kind: 'start' } | { kind: 'stop' }

function assertNever(value: never): never {
  throw new Error(`Commande inconnue : ${JSON.stringify(value)}`)
}

function run(command: Command): string {
  switch (command.kind) {
    case 'start':
      return 'Start'
    case 'stop':
      return 'Stop'
    default:
      return assertNever(command)
  }
}

console.log(run({ kind: 'start' }))
console.log(run({ kind: 'stop' }))
Résultat
Start
Stop
void comme type de retour est plus souple que never
TypeScript
const log: (message: string) => void = (message) => {
  console.log(message.toUpperCase())
  return message.length
}

log('html')
Résultat
HTML

Même si la fonction transmise renvoie réellement quelque chose, le type (message: string) => void demande de l’ignorer. Grâce à cela, des fonctions comme arr.forEach(x => list.push(x)) sont correctes, bien que push() renvoie un nombre.

Bonnes pratiques

#
  • Ajoutez void explicitement aux fonctions qui exécutent un effet de bord. Cela indique au lecteur qu’il ne devrait pas utiliser le résultat.
  • La fonction assertNever dans la branche default est un moyen simple de faire rappeler par le compilateur les nouvelles variantes d’une union.
  • N’essayez pas de déclarer une variable de type never à laquelle vous voulez affecter quelque chose. Aucune valeur, même undefined, ne correspond à ce type.

Entrées associées

#

Vous voyez une erreur ou il manque un exemple ? Écrivez-nous.