'What’s the difference between definite assignment assertion and ambient declaration?

When asserting that a field is definitely initialized in a class, what’s the difference between ! (exclamation point, definite assignment assertion) and the declare modifier?

The following code is an error in strict mode since TS doesn’t know for sure that the field has been initialized.

class Person {
    name: string; // Error: Property 'name' has no initializer and is not definitely assigned in the constructor.
}

I’ve seen 2 ways of handling this:

  1. Definite assignment assertion:
    class Person {
        name!: string;
    }
    
  2. Ambient declaration:
    class Person {
        declare name: string;
    }
    

I can’t see the difference between these two techniques. They both cure the error, they both don’t emit code, and they both don’t allow initializers. Does ambient declaration (released in v3.7) simply outdate definite assignment (released in v2.7)? Should declare be used instead of ! whenever possible?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source