0

I'm looking to create an angular directive inspired in the ngxs/form-plugin

Searching their code I found something interesting:

@Input('ngxsForm')
  path: string = null!;

Why is the negation character at the end of the null?

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
J Rui Pinto
  • 354
  • 2
  • 9
  • 7
    That isn't JavaScript – Quentin Oct 28 '19 at 13:52
  • 2
    @MarcSances Even when applied to a literal value, as here? – Kyll Oct 28 '19 at 13:54
  • 4
    An extra wrinkle: `null!` in TypeScript is a "non-null `null`", which is impossible. The type of `null!` is [`never`](https://www.typescriptlang.org/docs/handbook/basic-types.html#never), the [bottom type](https://en.wikipedia.org/wiki/Bottom_type), and is assignable to all other types. Thus TypeScript will allow you use `null!` for a value of any type, such as `string` above. This is, of course, lying to the compiler; `null` is not a `string` at runtime. If you *want* to lie to the compiler and, e.g., pretend to initialize a class property when you haven't, `null!` is a terse way to do it. – jcalz Oct 28 '19 at 14:10
  • I wish this would be reopened; the question this supposedly duplicates is asking what `!` is in general, whereas this is specifically about `null!`. It's like "Q: Why did Michael Jackson wear his trademark single white glove? A: Gloves protect and comfort hands against cold or heat, damage by friction, abrasion or chemicals, and disease; or in turn to provide a guard for what a bare hand should not touch." – jcalz Apr 14 '22 at 15:01

1 Answers1

3

! is a typescript operator that asserts an expression is not null. This is called the non-null assertion operator and was added as a shorthand to silence strict null checking. The effect of ! is basically to take null out of the type of the expression it is applied to. So for example:

declare let x: string | null;
let y = x! // string

Normally path: string = null would not be valid since path is string and can't have null assigned to it. The type of null! is never since we are telling the compiler to take null out of the type of null we are left with no type which is never. As the sub-type of every type never is assignable to string

What we end up with is a field (path) that has a type that forbids null that is assigned in effect null. Such is the nature of assertions, they force the compiler to accept things it knows are invalid. Sometimes this is useful if the field is initialized by some other means, not sure about the exact use case you encountered.

Titian Cernicova-Dragomir
  • 230,986
  • 31
  • 415
  • 357