Skip to content

Some code written in strict mode is invalid in non-strict mode #17774

Closed
@kujon

Description

@kujon

TypeScript Version: 2.4.0

Code

Consider the following snippet:

const EMPTY_ARRAY = [];

Typescript infers EMPTY_ARRAY to be any[] and doesn't complain even with noImplicitAny turned on. Things get weirder, when we start using this variable:

const EMPTY_ARRAY = []; // Variable 'EMPTY_ARRAY' implicitly has type 'any[]' in some locations where its type cannot be determined.

const foo = () => EMPTY_ARRAY; // Variable 'EMPTY_ARRAY' implicitly has an 'any[]' type.

We get no implicit any error in 2 places. A questionable attempt at fixing this might be to type EMPTY_ARRAY as never[] or ReadonlyArray<never> which results in no errors:

const EMPTY_ARRAY: ReadonlyArray<never> = [];

const foo = () => EMPTY_ARRAY;

Questionability of this 'fix' aside, one would expect that turning off strictNullChecks would result in the code continuing to compile, but it's not the case:

// --strictNullChecks false
const EMPTY_ARRAY: ReadonlyArray<never> = [];
/** Type 'undefined[]' is not assignable to type 'ReadonlyArray<never>'.
  Types of property 'concat' are incompatible.
    Type '{ (...items: undefined[][]): undefined[]; (...items: undefined[][]): undefined[]; }' is not assignable to type '{ <U extends ReadonlyArray<never>>(...items: U[]): never[]; (...items: never[][]): never[]; (...i...'.
      Type 'undefined[]' is not assignable to type 'never[]'.
        Type 'undefined' is not assignable to type 'never'. */

const foo = () => EMPTY_ARRAY;

Expected behavior:
Not sure how this should be fixed tbh. To me it seems like never[] is not a type that should be allowed in either mode, since mutating the array will certainly break this. ReadonlyArray<never> looks like a valid option. On top of this, I'd expect that making the compiler less strict will keep the strict code compiling.

Actual behavior:
Described above.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions