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

Alias type conditions to desctrutured variables #46143

Closed
5 tasks done
ilogico opened this issue Sep 30, 2021 · 3 comments Β· Fixed by #46266
Closed
5 tasks done

Alias type conditions to desctrutured variables #46143

ilogico opened this issue Sep 30, 2021 · 3 comments Β· Fixed by #46266
Assignees
Labels
Fix Available A PR has been opened for this issue In Discussion Not yet reached consensus Suggestion An idea for TypeScript

Comments

@ilogico
Copy link

ilogico commented Sep 30, 2021

Suggestion

πŸ” Search Terms

is:issue is:open control flow analysis destructure

βœ… Viability Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

⭐ Suggestion

TypeScript 4.4 has a feature called Control Flow Analysis of Aliased Conditions and Discriminants, which essentially allows a variable to carry type information about another variable.
I believe something similar could happen when destructuring discriminated unions.

Object destructuring is a very common pattern in JavaScript, but we need to avoid it often in TypeScript because it loses type information:

declare var it: Iterator<number>;
const { value, done } = it.next();
if (!done) {
  value; // we know it's a number, but it's any
}

has to be artificially transformed to satisfy the typechecker:

const result = it.next();
if (!result.done) {
  result.value; // is narrowed to a number
}

With TypeScript 4.4, it looks like we're very close to having this feature:

const result = it.next();
const { value, done } = result;
if (!done) {
    result.value; // `done` tracks result's type
    value; // but not value's
}

πŸ“ƒ Motivating Example

These patterns emerge naturally in JavaScript and currently have to be transformed to fit TypeScript's ability to infer types.
The IteratorResult example above.
Another example is with action to state reducers:

type Action =
  | { type: 'A', payload: number }
  | { type: 'B': payload: string };

function reducer(state: Whatever, { type, payload }: Action) {
  switch (type) {
    case 'A':
      payload.toFixed();
      break;
    case 'B':
      payload.toUpperCase();
      break;
  }
}

πŸ’» Use Cases

I think the examples above already cover this.

@fatcerberus
Copy link

This looks similar in spirit to #35873

@ilogico
Copy link
Author

ilogico commented Sep 30, 2021

@fatcerberus, but maybe not as ambitious.
Anyway, I'm aware this should've been requested/reported multiple times.
But because TS4.4 brought a feature somewhat related to this, I thought I could use the opportunity to bring this up.

@IllusionMH
Copy link
Contributor

This case was explicitly mentioned in PR that implemented aliases #44730 (at the end, before list if fixed issues)
However not sure if there is big difference with #35873 or if there is better issue tracking correlation during destructuring only.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Fix Available A PR has been opened for this issue In Discussion Not yet reached consensus Suggestion An idea for TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants