Reputation: 6981
In TypeScript, I am trying to create a type guard for a function that allows type parameter T
to be any type that is not a Function
like this:
type Thunk<T> = (() => T) | T;
function unthunk<T extends Exclude<any, Function>>(x: Thunk<T>): T
{
if (typeof x === "function") return x();
return x;
}
But I am getting this error:
TS2349 Cannot invoke an expression whose type lacks a call signature. Type '(() => T) | (T & Function)' has no compatible call signatures.
How can I get my intended result? I am using TypeScript 3.4.
Edit: It seems that the typeof x === "function"
is causing the error, and I can work around that by simply casting x
. However, the type guard still does not work:
function unthunk<T extends Exclude<any, Function>>(x: Thunk<T>): T
{
if (typeof x === "function") return (x as () => T)();
return x;
}
unthunk<() => number>(() => () => 3); // there should be an error here but there is none
Upvotes: 0
Views: 292
Reputation: 254906
Wouldn't function overload do what you want
function unthunk<T>(x: () => T extends Function ? never : T): T;
function unthunk<T>(x: T extends Function ? never : T): T;
function unthunk<T>(x: T): T {
if (typeof x === 'function') {
return x();
}
return x;
}
const a = unthunk(1);
const b = unthunk(() => 1);
const c = unthunk(() => () => 1);
Upvotes: 1