简体   繁体   中英

How to prevent a member from being undefined within a constructor using TypeScript?

I have introduced a bug by writing a class like this:

class SomeClass {
    private readonly item: string;

    constructor(item: string) {
        // bug, item is never  assigned
    }

    public getInfo(): string {
        return this.item; // always returns `undefined`
    }
}

the item is never assigned and hence each call to getInfo() would return undefined . This code transpiles successfully though.

The code style of my current project is preventing the usage of the short-hand constructor via tslint's no-parameter-properties rule, and hence I cannot do:

class SomeClass {
    public constructor(private readonly item: string) {
    }

    public getInfo() {
        return this.item;
    }
}

I was expecting tsc to throw an error due to the strictNullChecks setting of my tsconfig.

Is there a way to make typescript detect this bug and mark its compilation as an error?

This is my current tsconfig.json compilerOptions:

  "compilerOptions": {
    "target": "ES6",
    "lib": [
      "es6",
      "es2017",
      "DOM"
    ],
    "module": "commonjs",
    "pretty": true,
    "outDir": "dist",
    "sourceMap": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "strictNullChecks": true,
    "forceConsistentCasingInFileNames": true,
  }

If you have tsc >=2.7.1, then you are either looking for the compiler options

--strict

Enable all strict type checking options. Enabling --strict enables --noImplicitAny , --noImplicitThis , --alwaysStrict , --strictNullChecks , --strictFunctionTypes and --strictPropertyInitialization .

as that contains all the strict rulesets.

Or more specifically for

--strictPropertyInitialization

as that one is designed for your use-case:

Ensure non-undefined class properties are initialized in the constructor. This option requires --strictNullChecks be enabled in order to take effect.

With that setting, tsc will now throw:

src/SomeClass.ts:2:22 - error TS2564: Property 'item' has no initializer and is not definitely assigned in the constructor.

2     private readonly item: string;
                       ~~~~

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM