Skip to content

Incorrect type inference for array rest assignment and inability to add annotation #21519

Closed

Description

@theseyi

TypeScript Version: 2.7.1-insiders.20180127

Search Terms: array destructuring rest assignment

Code

// A *self-contained* demonstration of the problem follows...
// Test this by running `tsc` on the command-line, rather than through another build tool such as Gulp, Webpack, etc.
const [stringA, ...numbers] = ['string', 1, 2];
// const [stringA, ...numbers] = <[string, number, number]>['string', 1, 2];
// const [stringA, ...numbers]: [string, number[]] = ['string', 1, 2];
// const [stringA, ...numbers]: [string, [number, number]] = ['string', 1, 2];

Expected behavior: Expect numbers to be of type number[] rather than (string | number)[].
TS also does not allow annotating as a tuple

Actual behavior: const numbers: (string | number)[]

Playground Link: http://www.typescriptlang.org/play/index.html#src=const%20%5BstringA%2C%20...numbers%5D%20%3D%20%5B'string'%2C%201%2C%202%5D%3B%0A%2F%2F%20const%20%5BstringA%2C%20...numbers%5D%20%3D%20%3C%5Bstring%2C%20number%2C%20number%5D%3E%5B'string'%2C%201%2C%202%5D%3B%0A%2F%2F%20const%20%5BstringA%2C%20...numbers%5D%3A%20%5Bstring%2C%20number%5B%5D%5D%20%3D%20%5B'string'%2C%201%2C%202%5D%3B%0A%2F%2F%20const%20%5BstringA%2C%20...numbers%5D%3A%20%5Bstring%2C%20%5Bnumber%2C%20number%5D%5D%20%3D%20%5B'string'%2C%201%2C%202%5D%3B

Related Issues:

Activity

  1. mhegazy commented on Jan 31, 2018

    @mhegazy
    Contributor

    Duplicate of #3369. A tuple type is not inferred in the absence of an explicit type annotation.

    you can find related discussions in #16656

  2. theseyi commented on Feb 1, 2018

    @theseyi
    Author

    A tuple type is not inferred in the absence of an explicit type annotation

    Mohamed Hegazy (@mhegazy) so how would the numbers rest assignment be annotated as a tuple? I believe I tried to this in the last line:

    const [stringA, ...numbers]: [string, [number, number]] = ['string', 1, 2];
  3. mhegazy commented on Feb 1, 2018

    @mhegazy
    Contributor

    The right type should be const [stringA, ...numbers]: [string, number, number]. and numbers should be inferred correctly. that is a bug we should fix.

  4. added
    BugA bug in TypeScript
    and removed
    DuplicateAn existing issue was already created
    on Feb 1, 2018
  5. sandangel commented on Feb 8, 2018

    @sandangel

    I have run into this issue too with overload function

    // I have tried this but it does not work
    interface OperatorTuple extends Array<OperatorFunction<any, any>> {
      0: OperatorFunction<any, any>;
      1: OperatorFunction<any, any>;
      2: OperatorFunction<any, any>;
      3: OperatorFunction<any, any>;
      4: OperatorFunction<any, any>;
      5: OperatorFunction<any, any>;
      6: OperatorFunction<any, any>;
      7: OperatorFunction<any, any>;
      length: 8;
    }
    
    // this is an overload function
    export function Select<A, B>(mapFn: ((state: A) => B), ...operators: OperatorFunction<any, any>[]) {
      return function(target: any, name: string): void {
        if (typeof mapFn !== 'function') {
          throw new TypeError(
            `Unexpected type '${typeof mapFn}' in select operator,` + ` expected 'function'`
          );
        }
    
        // trying to cast type tuple
        operators = [...operators] as OperatorTuple;
    
        const descriptor = Object.getOwnPropertyDescriptor(target, name);
    
        if (delete target[name]) {
          Object.defineProperty(target, name, {
            get() {
              const source$ = NgrxSelect.store;
    
              if (!source$) {
                throw new Error('NgrxSelect not connected to store!');
              }
    
             // I have tried this too but have failed
             if (operators.length > 8) {
                throw new Error()
             }
              
              // Error: Expect 0-9 arguments but received 1 or more
              return source$.pipe(select(mapFn), ...operators);
            },
            ...descriptor
          });
        }
      };
    }
  6. ajafff commented on Jul 27, 2018

    @ajafff
    Contributor

    The issue in the opening post is fixed in typescript@next, maybe even 3.0.0-rc.
    numbers is now of type number[].

  7. RyanCavanaugh commented on Oct 29, 2025

    @RyanCavanaugh
    Member

    It's now [number, number], even better (?)

  8. locked as resolved and limited conversation to collaborators on Jun 5, 2026
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

    BugA bug in TypeScriptDomain: check: Type InferenceRelated to type inference performed during signature resolution or `infer` type resolution

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions