I'd like to be distinguish the following function types in conditional type checks:
type SyncFn = () => void;
type AsyncFn = (data: number) => Promise<void>;
type SyncFnWithArg = (data: number) => void;
I also noticed that if I modify AsyncFn
and remove its argument then I have more problems since the type definition for onlySyncFn
is now incorrect since now it's "f1" | "f2"
instead of only being "f1"
as it is in the first TS Playground above.
I guess that's related with how function overloading in typescript is done, but I don't really know, so that's why I'm reaching out for help.... maybe it's not related, but are we able to do such function type distinction in TS?
CodePudding user response:
The problem can be addressed by changing the KeyOfType
type as follows:
- Check both directions of the type relationship (
A extends B
andB extends A
): - Wrap the types used in the conditional type clause in tuples (
[A] extends [B]
).
type KeyOfType<T, V> = keyof {
[P in keyof T as [T[P]] extends [V]
? [V] extends [T[P]]
? P
: never
: never
]: any
}
Find a playground example here, and an interesting discussion here about various ways to test for type equality (each with their own caveats).