Skip to content

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

Closed

Description

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.

Activity

  1. DanielRosenwasser commented on Aug 16, 2017

    @DanielRosenwasser
    Member

    Seems like the ergonomics of using [] in certain combinations are somewhat problematic. #16651 is related.

  2. RyanCavanaugh commented on Aug 16, 2017

    @RyanCavanaugh
    Member

    Daniel Rosenwasser (@DanielRosenwasser) what's the concrete change that's supposed to happen?

  3. ahejlsberg commented on Aug 16, 2017

    @ahejlsberg
    Member

    This is working as intended. See #11432 and #13779 for context. In particular, note that in --noImplicitAny mode we perform control flow analysis to determine the type of variables initialized with [].

    I'm perfectly happy to consider alternate proposals, but the currently behavior is a careful balance of performing better analysis when we can in --noImplicitAny mode while not breaking code when not in that mode.

  4. added
    Working as IntendedThe behavior described is the intended behavior; this is not a bug
    and removed
    Needs ProposalThis issue needs a plan that clarifies the finer details of how it could be implemented.
    on Aug 31, 2017
  5. mhegazy commented on Sep 18, 2017

    @mhegazy
    Contributor

    Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

  6. locked and limited conversation to collaborators on Jun 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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