Monday, January 15, 2018

Strict Property Initialization Checks in TypeScript 2.7

The upcoming version 2.7 release of TypeScript has a new compiler option available named "strictPropertyInitialization" This when set to true causes the compiler to ensure all properties in class instances are initialized. If they are not, a compiler error will be generated upon building for each uninitialized property.

As an aside, to get the most current version of TypeScript installed that hasn't yet been officially released you can run the following npm command:

npm install -g typescript@next

This installs the most recent nightly build which will allow me to have access to the new compiler option:

+ typescript@2.7.0-dev.20180113

If you are beginning a new project, wait to initialize your TypeScript project until after the newest version is installed, so you can easily see all the new compiler options. You can also add them manually to your existing tsconfig.json file. Upon initializing a fresh tsconfig file (tsc --init), you will see the new strictPropertyInitialization check:


/* Enable strict checking of property initialization in classes.*/
"strictPropertyInitialization": true, 

To test this, let's use the current simple TypeScript class:

class Person {
    firstName: string;
    lastName: string;
    address1: string;
    address2: number;
}

With "strictPropertyInitialization":true set, the following compiler errors will be emitted upon building:

error TS2564: Property 'firstName' has no initializer and is not definitely assigned in the constructor.
error TS2564: Property 'lastName' has no initializer and is not definitely assigned in the constructor.
error TS2564: Property 'address1' has no initializer and is not definitely assigned in the constructor.
error TS2564: Property 'address2' has no initializer and is not definitely assigned in the constructor.

This is exactly what we would expect. One way to satisfy the check we can do is mark the parameter as optional using the ? as we might with address2. This will remove the error related with this field, as undefined is acceptable:

class Person {
    firstName: string;
    lastName: string;
    address1: string;
    address2?: number;  //Optional field, type includes undefined
}

The build now only generates 3 errors:

error TS2564: Property 'firstName' has no initializer and is not definitely assigned in the constructor.
error TS2564: Property 'lastName' has no initializer and is not definitely assigned in the constructor.
error TS2564: Property 'address1' has no initializer and is not definitely assigned in the constructor.

To satisfy the strict property initialization for the rest of the class, we can initialize the remaining properties and we will get a successful build:

class Person {
    firstName: string = "Allen";
    lastName: string = "Conway";
    address1: string = "123 Main St";
    address2?: number;
}

There is also a way if needed to individually suppress the property initialization checks on an individual basis. This can be done by including a definite assignment assertion using a ! mark immediately after the property name. This will allow the following to build successfully:

class Person {
    firstName: string = "Allen";
    lastName: string = "Conway";
    address1!: string;  // Suppress strict initialization check
    address2?: number;
}

Visual Studio Code Error with TypeScript Project: "Option 'project' cannot be mixed with source files on a command line"

If you create a TypeScript project in Visual Studio code in a path that contains spaces, you might end up getting the following error after configuring your build task and building the application:
> Executing task: tsc -p "c:\Projects\Test Harness Applications\TypeScript\MyTypeScriptApp\tsconfig.json" <
error TS5042: Option 'project' cannot be mixed with source files on a command line.
The terminal process terminated with exit code: 1
Notice the path I used to create the application contained spaces: 
"c:\Projects\Test Harness Applications\TypeScript\MyTypeScriptApp"

After a little digging I found this GitHub open issue: https://github.com/Microsoft/vscode/issues/32400. The good news is according to the information within that link, this is in process to be fixed in an upcoming version of Visual Studio Code (currently 2/2018). In the interim the solution is just to make sure the full path to your application does not contain any spaces. I verified that by doing this, the compiler issue will go away, and the project build successfully.