Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I assert that a value is not a callable? #96

Closed
pastelmind opened this issue Apr 7, 2021 · 0 comments · Fixed by #104
Closed

How can I assert that a value is not a callable? #96

pastelmind opened this issue Apr 7, 2021 · 0 comments · Fixed by #104

Comments

@pastelmind
Copy link

pastelmind commented Apr 7, 2021

As of writing, expectError() does not support checking if a value is uncallable:

const Foo = 1;
expectError(Foo());       // ts(2349) This expression is not callable.
                          // Type 'Number' has no call signatures.

class MyClass {}
expectError(MyClass());   // ts(2348) Value of type 'typeof MyClass' is not callable.
                          // Did you mean to include 'new'?

When I run tsd, it complains with "Expected an error, but found none." for both examples above.

Some questions:

  1. Can expectError() be extended to add support for this? Does it need a new assertion function?
  2. Is this within the scope of tsd? Or should I just use // @ts-expect-error instead?

Edit: I did some experiments.

class Foo {}
const bar = 1;
function baz(): never { throw new Error(); }

// expectType<never>() is not good enough.
// It cannot distinguish uncallable values from functions that never return at all
// You also need @ts-expect-error anyway to stop TypeScript from complaining,
// but this defeats the purpose of using tsd in the first place.

// @ts-expect-error
expectType<never>(Foo());
// @ts-expect-error
expectType<never>(bar());
expectType<never>(baz());

// expectNotAssignable<Function>() isn't good enough because it doesn't catch
// attempting to call ES6 classes like plain functions.
// But this seems to work!

expectNotAssignable<CallableFunction>(Foo);
expectNotAssignable<CallableFunction>(bar);
expectAssignable<CallableFunction>(baz);

TL;DR: Use expectNotAssignable<CallableFunction>().

It might be nice to add this use case to the docs.

@pastelmind pastelmind changed the title expectError() for uncallables? How can I assert that a value is not a callable? Apr 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant