Skip to content

Destructing nested arrays/tuples does not infer type #38092

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

Closed
ryall opened this issue Apr 21, 2020 · 5 comments
Closed

Destructing nested arrays/tuples does not infer type #38092

ryall opened this issue Apr 21, 2020 · 5 comments

Comments

@ryall
Copy link

ryall commented Apr 21, 2020

TypeScript Version: Nightly

Search Terms:
"typescript array destructing types not working"

Expected behavior:
fieldName to be of type string
emptyValue to be of type any
expectedError to be of type string

Actual behavior:
fieldName is of type string | boolean
emptyValue is of type string | boolean
expectedError is of type string | boolean

Related Issues:
#32465

Code

// Fails
for (const [fieldName, emptyValue, expectedError] of [
    ['email', '', 'must enter an email address'],
    ['password', '', 'must enter a password'],
    ['tos', false, 'must accept the ToS'],
]) {
  fieldName.charAt(0);
}

// Works
const [fieldName, emptyValue, expectedError] = ['email', '', 'must enter an email address'];

fieldName.charAt(0);
Output
"use strict";
// Fails
for (const [fieldName, emptyValue, expectedError] of [
    ['email', '', 'must enter an email address'],
    ['password', '', 'must enter a password'],
    ['tos', false, 'must accept the ToS'],
]) {
    fieldName.charAt(0);
}
// Works
const [fieldName, emptyValue, expectedError] = ['email', '', 'must enter an email address'];
fieldName.charAt(0);
Compiler Options
{
  "compilerOptions": {
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": true,
    "strictBindCallApply": true,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "useDefineForClassFields": false,
    "alwaysStrict": true,
    "allowUnreachableCode": false,
    "allowUnusedLabels": false,
    "downlevelIteration": false,
    "noEmitHelpers": false,
    "noLib": false,
    "noStrictGenericChecks": false,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "esModuleInterop": true,
    "preserveConstEnums": false,
    "removeComments": false,
    "skipLibCheck": false,
    "checkJs": false,
    "allowJs": false,
    "declaration": true,
    "experimentalDecorators": false,
    "emitDecoratorMetadata": false,
    "target": "ES2017",
    "module": "ESNext"
  }
}

Playground Link: Provided

@ryall ryall changed the title Destructing typed arrays/tuples not working in for loop Destructing arrays/tuples does not infer type Apr 21, 2020
@nmain
Copy link

nmain commented Apr 21, 2020

In the playground link you provided, typescript is already giving you exactly the right error message at exactly the right place that tells you exactly why this won't work.

The left-hand side of a 'for...of' statement cannot use a type annotation.(2483)

Relevant discussion: #3500 (comment)

Edit: Looks like you've edited your code so this response isn't relevant anymore.

@ryall
Copy link
Author

ryall commented Apr 21, 2020

Yeah apologies, I have updated the code to demonstrate the problem more clearly.

@ryall
Copy link
Author

ryall commented Apr 21, 2020

I can fix the issue (for now) by explicitly defining the type of the tuple, with:

for (const [fieldName, emptyValue, expectedError] of [
    ['email', '', 'must enter an email address'],
    ['password', '', 'must enter a password'],
    ['tos', false, 'must accept the ToS'],
] as [string, any, string][]) {
  fieldName.charAt(0);
}

@ryall ryall changed the title Destructing arrays/tuples does not infer type Destructing nested arrays/tuples does not infer type Apr 21, 2020
@MartinJohns
Copy link
Contributor

I can fix the issue (for now) by explicitly defining the type of the tuple, with:

Without the type assertion you don't have a tuple, you just have an array. You can also use as const, it's intended for this.

Changing this behavior (infer tuple instead of array by default) would be a major breaking change.

@ryall
Copy link
Author

ryall commented Apr 21, 2020

OK thanks, makes sense.

@ryall ryall closed this as completed Apr 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants