Skip to content

Unexpected behavior in extends clause that has two inferred rest types with constraintsΒ #50993

Open
@Oblosys

Description

@Oblosys

Bug Report

πŸ”Ž Search Terms

  • extends constraint inferred rest
  • multiple inferred rest types

πŸ•— Version & Regression Information

Version 4.7 and higher (including nightly)

  • This is the behavior in every version I tried, and I reviewed the FAQ

⏯ Playground Link

TypeScript playground

πŸ’» Code

type Prefix<A> = A extends [...infer P extends 0[], 1] ? {p: P} : never

{ type Test = Prefix<[0,0,1]> }
// type Test = {p: [0, 0]}

{ type Test = Prefix<[0,0,1,1]> }
// type Test = never

type PrefixSuffix<A> = A extends [...infer P extends 0[], 1, ...infer S extends 0[]] ? {p: P, s: S} : never

{ type Test = PrefixSuffix<[0,0,1,0,0]> }
// type Test = {p: 0[], s: 0[]}

{ type Unexpected = PrefixSuffix<[0,0,1,1,0,0]> }
// type Unexpected = {p: 0[], s: 0[]}

πŸ™ Actual behavior

Similar to Prefix, which extracts a tuple of leading zeroes and works as expected, I tried to construct PrefixSuffix, to extract both the leading and trailing zeroes. When applied to an array with multiple ones, PrefixSuffix<[0,0,1,1,0,0]> evaluates to {p: 0[], s: 0[]} instead of never.

πŸ™‚ Expected behavior

I would have expected PrefixSuffix<[0,0,1,1,0,0]> to evaluate to never, as [0,0,1,1,0,0] cannot extend an array that contains only a single 1. I also would have expected PrefixSuffix<[0,0,1,0,0]> to infer tuple types {p: [0,0], s: [0,0]} rather than {p: 0[], s: 0[]}, but maybe that's just a design limitation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions