Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strict mode static property is undefined (no compiler error) #40649

Closed
Doccos opened this issue Sep 19, 2020 · 6 comments
Closed

Strict mode static property is undefined (no compiler error) #40649

Doccos opened this issue Sep 19, 2020 · 6 comments
Labels
Duplicate An existing issue was already created

Comments

@Doccos
Copy link

Doccos commented Sep 19, 2020

TypeScript Version: 4.0.3
IDE: PHPStorm 2020.2

Search Terms: strictPropertyInitialization static property undefined

tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "sourceMap": true,
    "strict": true
  },
  "exclude": [
    "node_modules"
  ]
}

Code

class StaticUndefined {

    
    private static props: { 
        test: string,
        test2: number
    }; //should be undefined
    
    public static getProps() {
        console.log(typeof StaticUndefined.props); // is undefined // no error during compile or in IDE (strictPropertyInitialization not triggert)
        console.log(typeof StaticUndefined.props.test); //error
        console.log(StaticUndefined.props.test); //error
        
    }
}

StaticUndefined.getProps();

Expected behavior:
The compiler and IDE should warn me that "props" may be "undefined" and should check their status

Actual behavior:
It will compile and the IDE will not show an error, but the script will crash (StaticUndefined.props is undefined).

Playground link

Related Issues:

@yw662
Copy link

yw662 commented Sep 19, 2020

This is a interesting one for me, and I tried something similar to this issue,

    private static props: { 
        test: string,
        test2: number
    } = undefined

or

    private static props: { 
        test: string,
        test2: number
    } = {}

Will raise the expected error.

For me this is like

let a: number

which is actually legal since you might assign to it later.

However,

    private static readonly props: { 
        test: string,
        test2: number
    }

won't raise the error either, when

const a: number

is not good.

And for instance members, like,

    private props: { 
        test: string,
        test2: number
    };

It always works as expected if they are not assigned in some constructors.

I guess there are some difficulties to let static mutable members be checked this way: If non-assigning declaration is disallowed for static mutable members, then non-assigning variable declaration should also be disallowed.
Besides, these mutable members, can be write-only members or setters. If a member is write-only, they should not be assigned on declaration. Although a private writeonly foo is not a private foo, which implies read-write, anyway.

However, static read-only members should be forced to be assigned, this is anyway a bug, and const foo is also forced to be assigned.

For the type check on the getProps() side, this is somewhat a working-as-intended: the variable is not declared optional, so they "cannot" be undefined.
For me there is a work around if you want the type check enforced on runtime: declare them as optional, like

    private static props?: { 
        test: string,
        test2: number
    };

Then getProps will know they might be undefined.

@Doccos
Copy link
Author

Doccos commented Sep 20, 2020

Yes, the workaround works, but is not perfect.
This should be done automatically to avoid mistakes.
So for

private static f: number;

It is declared as a number, but not initialized, so it should be of type "number | undefined" but is of type "number".

@yw662
Copy link

yw662 commented Sep 20, 2020

For me I would rather non-assigning non-optional declaration being disallowed. That's to say, the question mark in static foo?, and undefined in let a: number | undefined should be enforced.

However this is too much as a breaking change.

@jack-williams
Copy link
Collaborator

Duplicate of #27899?

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Sep 21, 2020
@RyanCavanaugh
Copy link
Member

👆

@typescript-bot
Copy link
Collaborator

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

5 participants