Skip to content

Narrowing of mapped types fails #50504

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
erik-kallen opened this issue Aug 29, 2022 · 4 comments
Closed

Narrowing of mapped types fails #50504

erik-kallen opened this issue Aug 29, 2022 · 4 comments
Labels
Duplicate An existing issue was already created

Comments

@erik-kallen
Copy link

erik-kallen commented Aug 29, 2022

Bug Report

Sometimes narrowing of discriminated unions fails with mapped types. See the attached playground

πŸ”Ž Search Terms

narrowing mapped types

πŸ•— Version & Regression Information

Happens in latest. don't know about other versions.

⏯ Playground Link

https://www.typescriptlang.org/play?#code/C4TwDgpgBAglC8UDeUCGAuKByVWDcUARpgHYCuAtoRAE4EAepl1NUAvlAD7JqZaH4oAY0wBnYDQCWJAOYMmVWgTYAoFaEhQAcgHsAGgB4AKgD4EUAPIVJwYwBps9LCbxqA9G6gB1HTQDWomiBEPSQQsAQACYqAGZkJOGSOiRQMQCMABRgmDAAlMgqUFCiAO42QgAWUFkAdKj5SIVFwqii0DhY6E3NwsmiOgA2EDUDOjK1hLmuPUWENBCoftPNQq3tAl0zvST9QyNjtUJT3c1zC0tNqqoqHlAAEq1QGtC0NL7BAG4QKcAVOmQyKq-WjQSSBEg6KDzVrJVK+KA2WLxRKwmIAJiymF0hhgJgaTVK5SqtXqBR6qza2FwmxmQj6g2Go3GYBqk2WPTOi3ZLUp-E6JyKdJ2DP2zJqR25s2hFyKVxUQA

πŸ’» Code

type A = { a: 'a'; b: number; x: number } | { a: 'b'; c: string; x: number; }

type NoX<T> = Omit<T, 'x'>;

// Works as expected
function f1(p: A) {
  switch (p.a) {
    case 'a':
      console.log(p.b);
      break;
    case 'b':
      console.log(p.c);
      break;
  }
}

// Has type errors even though there is no reason for it
function f2(p: NoX<A>) {
  switch (p.a) {
    case 'a':
      console.log(p.b);
      break;
    case 'b':
      console.log(p.c);
      break;
  }
}

πŸ™ Actual behavior

TypeScript does not realize that the member p.b exists if p.a === 'a' in the function f2

πŸ™‚ Expected behavior

The function f2 should typechek without errors, since it does not in any way touch or care about the removed member x.

@whzx5byb
Copy link

whzx5byb commented Aug 29, 2022

p is narrowed only when it's type is a discriminated union. A is, but Omit<A, 'x'> is not.

To produce your expected behavior you need a "distributive" omit type to produce a discriminated union result:

type DistributiveOmit<T, K extends string | number | symbol> = T extends unknown ? Omit<T, K> : never;
type NoX<T> = DistributiveOmit<T, 'x'>;

@erik-kallen
Copy link
Author

Then perhaps this should be considered a feature request to make Omit<A, 'x'> stay a discriminated union if A is one.

The suggested hack is way out of reach for the regular devleoper.

@jcalz
Copy link
Contributor

jcalz commented Aug 29, 2022

Duplicate of #31501

@jakebailey jakebailey added the Duplicate An existing issue was already created label Sep 2, 2022
@typescript-bot
Copy link
Collaborator

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

5 participants