Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

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.

Comments on TypeScript is unable to infer the correct type for a mapped tuple

Post

TypeScript is unable to infer the correct type for a mapped tuple

+6
−0

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:

  1. 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.)

  2. How can I fix this other than explicitly calling test<string, string[]>(add)?

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.
Why should this post be closed?

1 comment thread

`test<string, string>(add);` does not work either (Type 'string' does not satisfy the constraint 'rea... (2 comments)
`test<string, string>(add);` does not work either (Type 'string' does not satisfy the constraint 'rea...
Jacob Raihle‭ wrote 6 months ago

test<string, string>(add); does not work either (Type 'string' does not satisfy the constraint 'readonly any[]') . Is there a typo in your first test function?

Moshi‭ wrote 6 months ago

Ah good catch, I must've meant test<string, string[]>. I've corrected it.