Skip to content

Comparing a tuple input to a variadic tuple no longer narrows itΒ #54048

@ssalbdivad

Description

@ssalbdivad

Bug Report

πŸ”Ž Search Terms

Tuple, variadic tuple, narrowing, parameters, generics, const parameters, readonly

πŸ•— Version & Regression Information

  • This changed between versions 5.0 and 5.1

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

type narrow<def> = def extends string
    ? def
    : def extends [unknown, ...unknown[]]
    ? def
    : {
          [k in keyof def]: narrow<def[k]>
      }

declare const parse: <def>(def: narrow<def>) => def


const result = parse([{ a: "foo" }])
//    ^?
// <5.1: [{a: "foo"}]
//  5.1: [{a: string}]

Description

During the pre const generic parameter-era, patterns similar to this one became widely used for narrowing an array input to a tuple. This particular case has been simplified down from ArkType's parser, but as you can see it is very easy to reproduce and it seems possible it could break existing functionality in other libraries.

The workaround I found for this that supported my use case was to narrow the array input iteratively, like this (simplified):

export type validateTupleLiteral<
    def extends readonly unknown[],
    result extends unknown[] = []
> = def extends [infer head, ...infer tail]
    ? validateTupleLiteral<tail, $, [...result, head]>
    : result

However this would probably not be intuitive for other users who may be affected by the change, and const parameters are still new enough that most libraries cannot adopt them yet (though they do fix the problem). @Andarist mentioned he thought it could be related to this change:

https://github.com/microsoft/TypeScript/pull/53709/files

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptFix AvailableA PR has been opened for this issue

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions