Description
π Search Terms
conditional type detect callable type parameter
β Viability Checklist
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- This isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
- This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals
β Suggestion
I'm looking for some way to detect if a callable type is generic and has type parameters.
LLMs are hallucinating an answer that would be nice if it worked:
type HasTypeParameter<T extends (...args: any[]) => any> =
T extends <G>(...args: any[]) => any ? true : false;
π Motivating Example
I have a utility type that wants to map the return value of a callable. However because as far as I know it's not possible to map a type-parametrized callable keeping its parametrization, we prefer to bail out in this case and maintain the original type.
Roughly it looks like
type MappedCallable<T extends Callable> = HasTypeParameter<T> extends true
? T
: (...args: Parameters<T>) => MappedResult<ReturnType<T>>;
π» Use Cases
I can achieve this detection in some case where the type of the callable is incompatible with a mapped callable were its type parameters inferred as any
.
type LimitedHasTypeArgument<T extends (...args: any[]) => any> =
((...args: Parameters<T>) => ReturnType<T>) extends T ? false : true
However this doesn't work in some more complex cases (still trying to get a minimal repro).
I cannot think of other workarounds, which is forcing us to forego the result type mapping completely.
Of course having a way to keep the callable type-parametrization in the result mapping would be even better.
The specific use case is to map all callable in the result, including object methods, to callables returning a promise, while maintaining other parts of their signature.