Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
TypeScript is unable to infer the correct type for a mapped tuple
I was playing around with mapped tuples and came across an interesting case where TypeScript cannot infer the types used:
interface Foo<A, B> {
(a: A, b: B): any
}
function test<A, Bs extends readonly any[]>(...args: { [K in keyof Bs]: Foo<A, Bs[K]> }) {}
let add: Foo<string, string> = (a, b) => a + b;
test(add);
error TS2345: Argument of type 'Foo<string, string>' is not assignable to parameter of type 'Foo<unknown, string>'.
Type 'unknown' is not assignable to type 'string'.
80 test(add);
~~~
Interestingly, this succeeds if Foo
is an object interface; ex.
interface Foo<A, B> {
a: A,
b: B,
}
function test<A, Bs extends readonly any[]>(...args: { [K in keyof Bs]: Foo<A, Bs[K]> }): A {
throw "unimplemented";
}
let foo: Foo<string, string> = {a: '', b: ''};
let str = test(foo);
Though looking at my IDE, and adding a small compile time assertion shows that it actually can't correctly infer the type of this either; A
(and thus str
) has an inferred type of unknown
, so the problem still shows up, it just doesn't immediately cause an error in this case.
let string_assert: typeof str extends string ? true : never = true;
error TS2322: Type 'boolean' is not assignable to type 'never'.
13 let string_assert: typeof str extends string ? true : never = true;
Thus, my question is two-fold:
-
Why does TypeScript fail to infer the correct type in these cases? (Keep in mind that the concrete types for the passed argument should be known; they are even explicitly written.)
-
How can I fix this other than explicitly calling
test<string, string[]>(add)
?
1 comment thread