Issue
I'm having trouble understanding the following type definition:
type MergeHandlersReturnType<H extends Record<string, any>> = {
[K in keyof H]: ReturnType<H[K]>
}[keyof H]
Decomposing the above definition using similar types I'm not getting why the following is giving me compiler errors
interface R1 extends Record<string, any> {
"key1": () => 0|1
}
const v1: R1 = {
"key1": () => 1,
"key2": () => 2,
"key3": () => 3
}
type Merged<R1> = {
[K in keyof R1]: ReturnType<R1[K]>
^^^^^
}[keyof R1]
Type 'R1[K]' does not satisfy the constraint '(...args: any) => any'.
Type 'R1[keyof R1]' is not assignable to type '(...args: any) => any'.
Type 'R1[string] | R1[number] | R1[symbol]' is not assignable to type '(...args: any) => any'.
Type 'R1[string]' is not assignable to type '(...args: any) => any'.ts(2344)
I was expecting the Merged type to be the unions of the return types of the keys of R1 but the indexing is failing.
Solution
There are a couple of reasons why you are seeing a compiler error:
Merged<R1>is stating thatR1is a name of a generic type variable, not theR1interface, henceR1inMergedis pretty much like genericTwhich has no type definition and hypothetically has no properties that can be accessed viaT[K].After changing
Merged<R1>toMerged, becauseRecordhas a type ofanyininterface R1 extends Record<string, any> {, the resultingMergedunion type will always beany...ReturnTypein[K in keyof R1]: ReturnType<R1[K]>looks at what the second parameter ofRecordis as it is the broader one and does not analyze the properties inside theR1interface. To fix this, I would advise you to add a specific type instead of theanylike so:interface R1 extends Record<string,() => 0|1|2|3> {. Ofcourse another way would be to get rid of the extends and define your keys with your types so you wouldn't have to define the union type manually and useMergedlike you want to:
interface R1 {
"key1": () => 0|1
"key2": () => 2,
"key3": () => 3
}
It really depends on your use case and hopefully above explains why you are seeing the error in your question.
Here is a link to the playground.
Answered By - Ovidijus Parsiunas
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.