Skip to content

Commit 0060a38

Browse files
authored
Recommend declare instead of disabling strictPropertyInitialization
Since TypeScript 3.7, which was released in November 2019, TypeScript supports declaring properties which will be initialized in a way that is invisible to TS via the `declare` property modifier. This enables using `strictPropertyInitialization` with class or field decorators (as well as other patterns which can initialize classes invisibly to TS).
1 parent fd0f686 commit 0060a38

1 file changed

Lines changed: 25 additions & 21 deletions

File tree

docs/_guide/decorators.md

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -37,27 +37,31 @@ class HelloWorldElement extends HTMLElement {
3737

3838
Class Field decorators get given the class and the field name so they can add custom functionality to the field. Because they operate on the fields, they must be put on top of or to the left of the field.
3939

40-
#### Disabling `strictPropertyInitialization`
41-
42-
TypeScript comes with various "strict" mode settings, one of which is `strictPropertyInitialization` which TypeScript catch potential class properties which might not be assigned during construction of a class. This option conflicts with Catalyst's `@target`/`@targets` decorators, which safely do the assignment but TypeScript's simple heuristics cannot detect this. It's recommended to disable this option (other strict mode rules can still apply) in your `tsconfig.json` like so:
43-
44-
```json
45-
{
46-
"compilerOptions": {
47-
"strict": true,
48-
"strictPropertyInitialization": false
49-
}
50-
}
51-
```
52-
53-
If you really want to keep the `strictPropertyInitialization` option set to `true`, another option would be to use TypeScript's [non-null assertion operator (`!`)](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator), adding this to each of your `@target`/`@targets` properties, like so:
54-
55-
```typescript
56-
class HelloWorldElement extends HTMLElement {
57-
@target something!: HTMLElement
58-
@targets items!: HTMLElement[]
59-
}
60-
```
40+
#### Supporting `strictPropertyInitialization`
41+
42+
TypeScript comes with various "strict" mode settings, one of which is `strictPropertyInitialization` which TypeScript catch potential class properties which might not be assigned during construction of a class. This option conflicts with Catalyst's `@target`/`@targets` decorators, which safely do the assignment but TypeScript's simple heuristics cannot detect this. There are two ways to work around this:
43+
44+
1. Use TypeScript's [`declare` modifier](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#the-usedefineforclassfields-flag-and-the-declare-property-modifier) to tell TypeScript that the decorated field will still be set up correctly:
45+
46+
```typescript
47+
class HelloWorldElement extends HTMLElement {
48+
@target declare something: HTMLElement
49+
@targets declare items: HTMLElement[]
50+
}
51+
```
52+
53+
Note that this only works on TypeScript 3.7+, so if you're on an older version, you can also use the [definite initialization operator](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#definite-assignment-assertions) to do the same thing.
54+
55+
2. You can also disable the compiler option (other strict mode rules can still apply) in your `tsconfig.json` like so:
56+
57+
```json
58+
{
59+
"compilerOptions": {
60+
"strict": true,
61+
"strictPropertyInitialization": false
62+
}
63+
}
64+
```
6165

6266
### Method Decorators
6367

0 commit comments

Comments
 (0)