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

Nested Omit type with same constraints incompatible. #54508

Closed
Chr15t0pher opened this issue Jun 3, 2023 · 2 comments
Closed

Nested Omit type with same constraints incompatible. #54508

Chr15t0pher opened this issue Jun 3, 2023 · 2 comments
Labels
Duplicate An existing issue was already created

Comments

@Chr15t0pher
Copy link

Chr15t0pher commented Jun 3, 2023

Bug Report

πŸ”Ž Search Terms

nested Omit, util type

πŸ•— Version & Regression Information

  • This is the behavior in every version i tried on the typescriptlang playground.

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

interface Exotic {
  id: string
}

type WithoutExotic<P extends Record<string, unknown> = {}> = Omit<P, 'id'>

type WithExotic<P extends Record<string, unknown> = {}> = WithoutExotic<P> & Exotic

function fn<P extends Record<string, unknown>>(args: WithExotic<P>): WithoutExotic<P>{
  const { id, ...rest} = args
  return rest    // errors, not assignable
}

πŸ™ Actual behavior

Error occurs at line 12. First line in error message says Type 'Omit<WithExotic<P>, "id">' is not assignable to type 'WithoutExotic<P>'., however, second line shows Type 'Exclude<keyof P, "id">' is not assignable to type 'Exclude<Exclude<keyof P, "id">, "id">'., the assignment direction described is reverse.

Type 'Omit<WithExotic<P>, "id">' is not assignable to type 'WithoutExotic<P>'.
  Type 'Exclude<keyof P, "id">' is not assignable to type 'Exclude<Exclude<keyof P, "id">, "id">'.
    Type 'keyof P' is not assignable to type 'Exclude<Exclude<keyof P, "id">, "id">'.
      Type 'string | number | symbol' is not assignable to type 'Exclude<Exclude<keyof P, "id">, "id">'.
        Type 'string' is not assignable to type 'Exclude<Exclude<keyof P, "id">, "id">'.
          Type 'keyof P' is not assignable to type 'Exclude<keyof P, "id">'.

πŸ™‚ Expected behavior

  • There should be no error. Omit<WithExotic<P>, "id"> is assignable to type WithoutExotic<P>. Because Omit<Omit<P, K>, K> is equivalent to Omit<P, K> when P and K stay the same.
  • Better error messages. The assignment direction of first two error messages is reverse, it should not happened in typescript which allow variance.
@jcalz
Copy link
Contributor

jcalz commented Jun 3, 2023

This appears to be a duplicate of issue #37768, which is categorized as a bug. However, I believe it may be more of a design limitation. A similar issue is discussed in #43846, classified as a design limitation, and in #28884, classified as a feature request. So I'm uncertain as to the fate of this issue.

The root problem in all of these cases is that TypeScript struggles to infer much about conditional types that depend on generic type parameters, even in situations where it seems obvious to human developers. Unlike humans, who can reason abstractly and understand the meanings of words like "Exclude" and "Omit," the compiler must rely on a heuristic algorithm that is designed to meet performance constraints.

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Jun 12, 2023
@typescript-bot
Copy link
Collaborator

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

@typescript-bot typescript-bot closed this as not planned Won't fix, can't repro, duplicate, stale Jun 15, 2023
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

4 participants