Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Structural never type breaks conditional typesΒ #57210

Copy link
Copy link
@rotu

Description

@rotu
Issue body actions

πŸ”Ž Search Terms

never, intersection, contradiction

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about never

⏯ Playground Link

https://www.typescriptlang.org/dev/bug-workbench/?#code/PTAEBUAsFMGdtANwIYCcCWyAu6D2A7WUA0faRaVUNBAI1y0lFWgAddUtoATUWgT1Dp8XADaj08QgmREABmQqo5AOgCwAKBARI2AORFkoVqly1R0ALZ9oAY2QBXeKEbRBtaLoqhu6AGZ+lNAiooLC1KCwDrRYFqAA7sj8mlj8rAgAcriWwsiiGeSUoAC8pIWomtqgoAB6APwpaQgAylioDrZYDqh5BUoloADeAB4AXACMAL6gAGRDYwBMk5Vg1fWaK6AA6gjx6OI2oNDDrKIcwgDmLpCSCeiM13QO+zj4oABK0F2o+OBNoBdgpR0LYXE1Nql0h8vt1fk0ADzgI7DLj4bhEAAUKmxaAusFG1Hw-AAlCUAHyE-gU0pI46o9GgLE41B4gnIImk4oU4SBKjvUB1D6gNlEgDcGy0YE+3zhUNsBFgbWQwiIrgBQIwoNguFIBAAtPZxMhzAhIXAAehvEYnNA-A5REdUKYqJY4LBkIDNgABLCwPXHdKdf1OjiNKHvAAMA2lsL+6XhIwmkwp2koztAeqQlEEMFErDtogAhBLtApynIhKqWNgeJFA5hxO5BGr5Wj7nh8HkwXKFW0OlgITBQK3fDgCF3brBIBwsAb0KhbM8uLx2bwWwRRx2u+Q8g4a6qdWWlBWVVxkLxcH4jvcYFQ1X2EBxQH48s5aD18LZIOoNGaPuNoxhH442geFFEoFMwHAipJWqWoGg0TZaAcLA7gedkhEsdhYFgdATSEERKHgToOwAGk2cYVEebsEFbRUemEVDuFwc18AYUAAGsQQ4gjqEMSJkECC491QbhNgWKj1zbMdOwdW42NQqcZznBcl1rLAdT0aC9E2ABmSShxHdtxwdHdRD3LgD2oh8+A-L9iHwUIjgoN5GFwBwLiYVwWAMXVmGgWQSA04wWF5a9vNs9kv0HBAWBlGjKwI3kWBXeQHHwDi2PifA5FIyJoCsS4nI8ewbSELBfIwhxWHSKh6HSi9XKHP9WDQZBXS4GDtD-d4FgGdLMtwbLRWRQNlzKJQwwQXrAJlECEzGKZZnmUYljJTY1gQzZCjefwIji2EEtuAAqej+26PJQmOnw7FEGhuDy+5EvQC42JSvhm3+Hkgk-aAIX+d5dP6jKsvwEaAzscaACIAA0oamj4gdKGNgIRRMlrmRMlmWjEmRUXF8UpABtABdTkKVhqHiXW2DNqAA

πŸ’» Code

// These variations on never are both reported by intellisense as `never`.
// That's a problem because they behave differently in a subtle way
type NominalNever = never
//   ^?
type StructuralNever = {x:1} & {x:2}
//   ^?

// We will be exploring this with the builtin ReturnType generic type
// type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;

// ReturnType constrains the generic so non-callable types give a useful error message
// @ts-expect-error
type R0 = ReturnType<{x:1}> // error - very helpful!

// `never` is treated specially by the conditional type construct
// the conditional is short-circuited and the conditional evaluates to `never` instead of either the true or false branch.
type R1 = ReturnType<never> // never
//   ^?

// but with an impossible intersection,
// 1. the type constraint does not kick in as a safeguard
// 2. the conditional is not short-circuited to 'never'
// 3. the conditional evaluates to the true branch only even though there's no reason to prefer either branch
// the return type is inferred as `unknown`, seemingly because it's an upper bound on the type parameter
// type R2 = unknown; expected never
type R2 = ReturnType<{x:1} & {x:2}>
//   ^?

// even if a return type is *structurally* declared, it is ignored by type inference
// type R3 = unknown; expected "X"
type R3 = ReturnType<{x:1} & {x:2} & ((...args: any[]) => "X")>
//   ^?

πŸ™ Actual behavior

When intersecting two object types with a conflicting value, the user-observable hinted type is never, but the type interacts with generic templates in a nonsensical way.

πŸ™‚ Expected behavior

I expect either (or both):

  1. conflicting intersections to treated the same as the nominal never type for constrained generics and conditional types. In particular:
    • The generic constraint would need to be (re)checked, so that an error is reported if the type constraint is refuted.
    • The conditional type will need to be (re)checked, so that the conditional is never
  2. conflicting intersections to be represented by their structural properties instead of an opaque "never" type.

Additional information about the issue

No response

Reactions are currently unavailable

Metadata

Metadata

Assignees

No one assigned

    Labels

    Not a DefectThis behavior is one of several equally-correct optionsThis behavior is one of several equally-correct options

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.