web-dev-qa-db-fra.com

Dans TypeScript, quelle est la! (point d'exclamation / coup) lors de la déréférence d'un membre?

En examinant le code source d'une règle tslint, je suis tombé sur la déclaration suivante:

if (node.parent!.kind === ts.SyntaxKind.ObjectLiteralExpression) {
    return;
}

Notez l'opérateur ! après node.parent. Intéressant!

J'ai d'abord essayé de compiler le fichier localement avec ma version de TS actuellement installée (1.5.3). L'erreur résultante a indiqué l'emplacement exact de la détonation:

$ tsc --noImplicitAny memberAccessRule.ts 
noPublicModifierRule.ts(57,24): error TS1005: ')' expected.

Ensuite, j'ai mis à niveau le dernier TS (2.1.6), qui l'a compilé sans problème. Donc, il semble être caractéristique de TS 2.x. Mais la transpilation a complètement ignoré la détonation, ce qui a entraîné le JS suivant:

if (node.parent.kind === ts.SyntaxKind.ObjectLiteralExpression) {
    return;
}

Mon fu Google m'a jusqu'ici échoué.

Qu'est-ce que l'opérateur du point d'exclamation de TS et comment ça marche?

300
Mike Chamberlain

C'est l'opérateur d'assertion non nul. C'est une façon de dire au compilateur "cette expression ne peut pas être null ou undefined ici, alors ne vous plaignez pas de la possibilité qu'elle soit null ou undefined." Parfois, le vérificateur de type est incapable de prendre cette décision lui-même.

C'est expliqué ici :

Un nouvel opérateur d'expression post-correctif ! peut être utilisé pour affirmer que son opérande est non nul et non indéfini dans des contextes où le vérificateur de type n'est pas en mesure de conclure ce fait. Plus précisément, l'opération x! génère une valeur du type x avec null et undefined exclue. Semblable aux assertions de type des formes <T>x et x as T, l'opérateur d'assertion non-null ! est simplement supprimé dans le code JavaScript émis.

Je trouve l'utilisation du terme "affirmer" un peu trompeur dans cette explication. C'est "assert" dans le sens où le développeur l'affirme , pas dans le sens où un test va être effectué. La dernière ligne indique en effet qu'il en résulte qu'aucun code JavaScript n'est émis.

450
Louis

La réponse de Louis est excellente, mais je pensais essayer de résumer succinctement:

L'opérateur bang demande au compilateur d'assouplir temporairement la contrainte "non nulle" qu'il pourrait autrement exiger. Il dit au compilateur: "En tant que développeur, je sais mieux que vous que cette variable ne peut pas être nulle pour le moment".

94
Mike Chamberlain