Skip to content

5.1 regression: constraints of generic tuple types are sometimes order-sensitive #54495

Closed

Description

Bug Report

🔎 Search Terms

  • 5.1
  • tuple
  • array
  • spread

Possibly related:

🕗 Version & Regression Information

  • This changed between versions v5.0.4 and v5.1.3

⏯ Playground Link

I was unable to reproduce: if you could please steer me in the right direction I'm happy to dig more, but I'm a bit stuck on how to debug this

💻 Code

We have an issue using io-ts. If this is a bug with that library, I'll close this here, but I don't think it is.

The TypeScript compiler is complaining about a number of excerpts from the d.ts file, where the compiler doesn't seem to be making sense.

Here's an example error:

node_modules/io-ts/lib/index.d.ts:1151:24 - error TS2344: Type 'CS' does not satisfy the constraint '[Mixed, Mixed, Mixed[]]'.
  Type '[Mixed, Mixed, ...Mixed[]]' is not assignable to type '[Mixed, Mixed, Mixed[]]'.
    Target allows only 3 element(s) but source may have more.

1151 ) => TaggedUnionC<Tag, CS>

The code it's referring to is here:

export interface TaggedUnionC<Tag extends string, CS extends [Mixed, Mixed, ...Array<Mixed>]>
  extends TaggedUnionType<Tag, CS, TypeOf<CS[number]>, OutputOf<CS[number]>, unknown> {}

export declare const taggedUnion: <Tag extends string, CS extends [Mixed, Mixed, ...Mixed[]]>(
  tag: Tag,
  codecs: CS,
  name?: string
) => TaggedUnionC<Tag, CS>

As you can see, the compiler seems to be collapsing the [Mixed, Mixed, ...Array<Mixed>] to [Mixed, Mixed, Mixed[]], which is incorrect. It then doesn't like CS extending [Mixed, Mixed, ...Mixed[]], which it considers incompatible with its incorrect collapsing.

Weirdly, if I tweak the d.ts file by hand, the error goes away:

- export interface TaggedUnionC<Tag extends string, CS extends [Mixed, Mixed, ...Array<Mixed>]>
+ export interface TaggedUnionC<Tag extends string, CS extends [Mixed, Mixed, ...Mixed[]]>

🙁 Actual behavior

Compilation errors

🙂 Expected behavior

Successful compilation

Activity

  1. RyanCavanaugh commented on Jun 2, 2023

    @RyanCavanaugh
    Member

    I'm not able to reproduce this error. Can you post a concrete example?

  2. alecgibson commented on Jun 2, 2023

    @alecgibson
    Author

    Ryan Cavanaugh (@RyanCavanaugh) I tried to put together an MWE but I couldn't figure it out.

    For some reason the error only happens with io-ts as a dependency of a dependency. The middle dependency compiles just fine with TS 5.1 and the issue only happens downstream with the transpiled JS and declaration files being used in 5.1.

    Do you have any advice on how to get more information from TS, or a good guess at what might be the actual issue for me to narrow my search?

  3. Andarist commented on Jun 5, 2023

    @Andarist
    Contributor

    I'd recommend bisecting your situation by removing code from your dependencies, once you minimize this to a minimal repro you might want to just commit node_modules and share that as a repro case.

  4. alecgibson commented on Jun 5, 2023

    @alecgibson
    Author

    Okay Ryan Cavanaugh (@RyanCavanaugh) Mateusz Burzyński (@Andarist) I've got a minimal repro repo.

    Turns out, nothing to do with our code, so either a TS bug, or a bug with another repo (still looks like TS to my uneducated eye, though).

    The repro case — in the end — was laughably simple:

    import 'mongodb';
    import 'io-ts';

    ☝🏼 this fails to build with a bare-bones tsconfig.json on TypeScript v5.1.3 with the compilation error I mentioned above.

    It builds fine on TypeScript v5.0.4.

  5. alecgibson commented on Jun 5, 2023

    @alecgibson
    Author

    Please let me know if this is actually a bug with mongodb or io-ts, and I'll move there, but building a project that just depends on one of these libraries works just fine:

    import 'mongodb';
    - import 'io-ts';

    or

    - import 'mongodb';
    import 'io-ts';

    both work

  6. alecgibson commented on Jun 5, 2023

    @alecgibson
    Author
    Full error dump
    ❯ npm run build
    
    > ts-spread-bug@1.0.0 build
    > tsc --pretty
    
    node_modules/io-ts/lib/index.d.ts:771:21 - error TS2344: Type 'CS' does not satisfy the constraint 'Any[]'.
      Type '[Mixed, Mixed, Mixed[]]' is not assignable to type 'Any[]'.
        Type 'Mixed | Mixed[]' is not assignable to type 'Any'.
          Type 'Mixed[]' is not assignable to type 'Type<any, any, any>'.
    
    771   extends UnionType<CS, TypeOf<CS[number]>, OutputOf<CS[number]>, unknown> {}
                            ~~
    
    node_modules/io-ts/lib/index.d.ts:771:32 - error TS2344: Type 'CS[number]' does not satisfy the constraint 'Any'.
      Type 'Mixed | Mixed[]' is not assignable to type 'Type<any, any, any>'.
        Type 'Mixed[]' is missing the following properties from type 'Type<any, any, any>': name, is, validate, encode, and 7 more.
    
    771   extends UnionType<CS, TypeOf<CS[number]>, OutputOf<CS[number]>, unknown> {}
                                       ~~~~~~~~~~
    
    node_modules/io-ts/lib/index.d.ts:771:54 - error TS2344: Type 'CS[number]' does not satisfy the constraint 'Any'.
    
    771   extends UnionType<CS, TypeOf<CS[number]>, OutputOf<CS[number]>, unknown> {}
                                                             ~~~~~~~~~~
    
    node_modules/io-ts/lib/index.d.ts:799:5 - error TS2344: Type 'CS' does not satisfy the constraint 'Any[]'.
      Type '[Mixed, Mixed, Mixed[]]' is not assignable to type 'Any[]'.
        Type 'Mixed | Mixed[]' is not assignable to type 'Any'.
          Type 'Mixed[]' is not assignable to type 'Type<any, any, any>'.
    
    799     CS,
            ~~
    
    node_modules/io-ts/lib/index.d.ts:807:48 - error TS2344: Type 'CS[2]' does not satisfy the constraint 'Any'.
      Type 'Mixed[]' is missing the following properties from type 'Type<any, any, any>': name, is, validate, encode, and 7 more.
    
    807       ? TypeOf<CS[0]> & TypeOf<CS[1]> & TypeOf<CS[2]>
                                                       ~~~~~
    
    node_modules/io-ts/lib/index.d.ts:824:54 - error TS2344: Type 'CS[2]' does not satisfy the constraint 'Any'.
      Type 'Mixed[]' is missing the following properties from type 'Type<any, any, any>': name, is, validate, encode, and 7 more.
    
    824       ? OutputOf<CS[0]> & OutputOf<CS[1]> & OutputOf<CS[2]>
                                                             ~~~~~
    
    node_modules/io-ts/lib/index.d.ts:846:58 - error TS2344: Type '[A, B, C, D, E]' does not satisfy the constraint '[Mixed, Mixed, Mixed[]]'.
      Source has 5 element(s) but target allows only 3.
    
    846 >(codecs: [A, B, C, D, E], name?: string): IntersectionC<[A, B, C, D, E]>
                                                                 ~~~~~~~~~~~~~~~
    
    node_modules/io-ts/lib/index.d.ts:850:18 - error TS2344: Type '[A, B, C, D]' does not satisfy the constraint '[Mixed, Mixed, Mixed[]]'.
      Source has 4 element(s) but target allows only 3.
    
    850 ): IntersectionC<[A, B, C, D]>
                         ~~~~~~~~~~~~
    
    node_modules/io-ts/lib/index.d.ts:854:18 - error TS2344: Type '[A, B, C]' does not satisfy the constraint '[Mixed, Mixed, Mixed[]]'.
      Type at position 2 in source is not compatible with type at position 2 in target.
        Type 'C' is not assignable to type 'Mixed[]'.
          Type 'Type<any, any, unknown>' is missing the following properties from type 'Mixed[]': length, pop, push, concat, and 29 more.
    
    854 ): IntersectionC<[A, B, C]>
                         ~~~~~~~~~
    
    node_modules/io-ts/lib/index.d.ts:1139:32 - error TS2344: Type 'CS' does not satisfy the constraint 'Mixed[]'.
      Type '[Mixed, Mixed, Mixed[]]' is not assignable to type 'Mixed[]'.
        Type 'Mixed | Mixed[]' is not assignable to type 'Mixed'.
          Type 'Mixed[]' is missing the following properties from type 'Type<any, any, unknown>': name, is, validate, encode, and 7 more.
    
    1139   extends TaggedUnionType<Tag, CS, TypeOf<CS[number]>, OutputOf<CS[number]>, unknown> {}
                                        ~~
    
    node_modules/io-ts/lib/index.d.ts:1139:43 - error TS2344: Type 'CS[number]' does not satisfy the constraint 'Any'.
      Type 'Mixed | Mixed[]' is not assignable to type 'Type<any, any, any>'.
        Type 'Mixed[]' is not assignable to type 'Type<any, any, any>'.
    
    1139   extends TaggedUnionType<Tag, CS, TypeOf<CS[number]>, OutputOf<CS[number]>, unknown> {}
                                                   ~~~~~~~~~~
    
    node_modules/io-ts/lib/index.d.ts:1139:65 - error TS2344: Type 'CS[number]' does not satisfy the constraint 'Any'.
    
    1139   extends TaggedUnionType<Tag, CS, TypeOf<CS[number]>, OutputOf<CS[number]>, unknown> {}
                                                                         ~~~~~~~~~~
    
    node_modules/io-ts/lib/index.d.ts:1151:24 - error TS2344: Type 'CS' does not satisfy the constraint '[Mixed, Mixed, Mixed[]]'.
      Type '[Mixed, Mixed, ...Mixed[]]' is not assignable to type '[Mixed, Mixed, Mixed[]]'.
        Target allows only 3 element(s) but source may have more.
    
    1151 ) => TaggedUnionC<Tag, CS>
                                ~~
    
    
    Found 13 errors in the same file, starting at: node_modules/io-ts/lib/index.d.ts:771
    
  7. Andarist commented on Jun 5, 2023

    @Andarist
    Contributor

    This can be bisected to this PR #53672 , cc Anders Hejlsberg (@ahejlsberg)

    That being said, this isn't quite a minimal repro case 😉 mongodb and io-ts have a lot of types and it might take a while for somebody to actually reduce this.

    Note that reordering those 2 imports also fixes the issue so it's likely a caching bug in the compiler. Things are cached for performance reasons and unfortunately, sometimes issues like this pop up and at times it's hard to fix them. Ideally, the order of declarations shouldn't matter but in practice, it sometimes might.

  8. alecgibson commented on Jun 5, 2023

    @alecgibson
    Author

    Sorry I guess I meant minimal in terms of code I actually wrote 😅

    Unfortunately I'm not sure I personally have time to unpick the internal type dependencies of these packages 😬

    Mateusz Burzyński (@Andarist) I'm not really sure I understand what the actual issue is: do you have a suggestion for a more accurate issue title for this?

  9. Andarist commented on Jun 5, 2023

    @Andarist
    Contributor

    Maybe something like: "5.1 regression: constraints of generic tuple types are sometimes order-sensitive"

  10. changed the title [-]5.1 Regression: Spread Array types inside tuple incorrectly collapsed[/-] [+]5.1 regression: constraints of generic tuple types are sometimes order-sensitive[/+] on Jun 5, 2023
  11. alecgibson commented on Jun 5, 2023

    @alecgibson
    Author

    Okay I spotted something as I was skimming the MongoDB type declarations, and it looks like if you comment out this suspicious-looking type (and things that depend on it), everything compiles just fine.

    I've pushed the result to the above repo as a new branch: commented-deps

    Is this a TypeScript bug or a MongoDB bug?

  12. alecgibson commented on Jun 28, 2023

    @alecgibson
    Author

    Mateusz Burzyński (@Andarist) Anders Hejlsberg (@ahejlsberg) this is still broken in 5.1.5. Should it be fixed?

  13. Andarist commented on Jun 28, 2023

    @Andarist
    Contributor

    It seems that the fix was supposed to be cherry-picked into 5.1 but the automated job failed, see the comment here. cc Daniel Rosenwasser (@DanielRosenwasser) Jake Bailey (@jakebailey)

  14. jakebailey commented on Jun 28, 2023

    @jakebailey
    Member

    I just sent #54814 to cherry-pick it by hand. Unfortunate; I totally read that notification in my email but I figured it was already handled...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Fix AvailableA PR has been opened for this issueNeeds More InfoThe issue still hasn't been fully clarified

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions