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.
interface TypeMap { STRING: string; NUMBER: number;}
type MapTypes<T> = {
[P in keyof T]: T[P] extends keyof TypeMap ? TypeMap[T[P]] : never
};
declare function fromArray<T extends ReadonlyArray<keyof TypeMap>>(
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 union
fromArray(['STRING', 'NUMBER', 'STRING'], ['abc', '123', 'xyz']); // no error
fromArray(['STRING', 'NUMBER', 'STRING'] as const, ['abc', '123', 'xyz']); // error
declare function fromTuple<T extends([] | ReadonlyArray<keyof TypeMap>)>(
types: T, params: MapTypes<T>): void;
fromTuple(['STRING', 'NUMBER', 'STRING'], ['abc', 123, 'xyz']); // ok
// T extends([]|MyType) cases the compiler to infer array as tuple
fromTuple(['STRING', 'NUMBER', 'STRING'], ['abc', '123', 'xyz']); // error
fromTuple(['STRING', 'NUMBER', 'STRING'] as const, ['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 PR
This PR includes a similar test, but it there is no test for empty tuple and array combination #26676