== Why is this an issue?

In TypeScript, casts and non-null assertions are two mechanisms used to inform the TypeScript compiler about the intended types of variables, expressions, or values in the code. They are used to help the compiler understand the types more accurately and to handle certain situations where type inference might not be sufficient:

* A type assertion tells the compiler to treat the value as the specified type, even if the compiler's type inference suggests a different type.
* A non-null assertion is a way to tell the TypeScript compiler explicitly that you are certain that a variable will not be ``++null++`` or ``++undefined++``, and you want to access its properties or methods without any null checks.

However, a redundant cast occurs when you perform a type assertion that is not needed because the compiler already knows the type based on the context or explicit type declarations. Similarly, a redundant non-null assertion occurs when you use the non-null assertion operator ``++!++`` to assert that a variable is not ``++null++`` or ``++undefined++``, but the compiler already knows that based on the context.

Both redundant casts and redundant non-null assertions should be avoided in TypeScript code, as they add unnecessary noise, clutter the code, and lead to confusion.

[source,javascript,diff-id=1,diff-type=noncompliant]
----
function getName(x?: string | Person) {
  if (x) {
    console.log("Getting name for " + x!); // Noncompliant: 'x' is known to be defined here

    if (typeof x === "string") {
      return (x as string); // Noncompliant: 'x' is known to be a string here
    } else {
      return (x as Person).name; // Noncompliant: 'x' is defined and not a string, thus a 'Person' here
    }
  }
  return "NoName";
}
----

Remove all the redundant casts and non-null assertions based on the contextual typing information, as inferred by the TypeScript compiler.

[source,javascript,diff-id=1,diff-type=compliant]
----
function getName(x?: string | Person) {
  if (x) {
    console.log("Getting name for " + x);

    if (typeof x === "string") {
      return x;
    } else {
      return x.name;
    }
  }
  return "NoName";
}
----

== Resources
=== Documentation

* TypeScript Documentation - https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#type-assertions[Type Assertions]
* TypeScript Documentation - https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#non-null-assertion-operator-postfix-[Non-null Assertion Operator (Postfix ``++!++``)]

ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

=== Message

Remove this unnecessary [cast|not-null assertion].


=== Highlighting

The cast or not-null assertion.


'''
== Comments And Links
(visible only on this page)

=== on 14 Nov 2017, 20:56:16 Ann Campbell wrote:
\[~jeanchristophe.collet] "and when property values set at type definition are checked" is not clear to me. Would it be fair to reword to something like:


____
inside conditions that test the object type, either with ``++.kind++`` or ``++instanceof++``

____
?

endif::env-github,rspecator-view[]
