Skip to content

Extending empty tuple in generic functions causes compiler to infer arrays as tuples #31434

Description

TypeScript Version: 3.4.5

Search Terms:
empty tuple, type inference, generic function

Code
Basically I'm writing a generic function with dynamic type mapping. I think this use case is pretty common for database drivers and JSON validators and I found some related issues. There is a workaround and I want to confirm whether it is intended behavior or a bug.

interfaceTypeMap{STRING: string;NUMBER: number;}typeMapTypes<T>={[PinkeyofT]: T[P]extendskeyofTypeMap ? TypeMap[T[P]] : never};declarefunctionfromArray<TextendsReadonlyArray<keyofTypeMap>>(types: T,params: MapTypes<T>): void;fromArray(['STRING','NUMBER','STRING'],['abc',123,'xyz']);// ok// the default behavior is to infer types in array as type unionfromArray(['STRING','NUMBER','STRING'],['abc','123','xyz']);// no errorfromArray(['STRING','NUMBER','STRING']asconst,['abc','123','xyz']);// errordeclarefunctionfromTuple<Textends([]|ReadonlyArray<keyofTypeMap>)>(types: T,params: MapTypes<T>): void;fromTuple(['STRING','NUMBER','STRING'],['abc',123,'xyz']);// ok// T extends([]|MyType) cases the compiler to infer array as tuplefromTuple(['STRING','NUMBER','STRING'],['abc','123','xyz']);// errorfromTuple(['STRING','NUMBER','STRING']asconst,['abc','123','xyz']);// error

Expected behavior:
Type of the array literal is inferred as array of union type.

Actual behavior:
Type of the array literal is inferred as tuple when T extends []|MyType is used in generic function.
I'd prefer it to be the expected behavior, but I didn't find any tests for that use case.

Playground Link:
You can see the same behavior in the playground

Related Issues:
#13151
#22679

Related PR
This PR includes a similar test, but it there is no test for empty tuple and array combination #26676

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions