Is there a type in TypeScript for anything except functions?

New Feature Answer

Added November 2018 – as conditional types are a thing now!

Conditional types provide a possible solution to this, as you can create a NotFunction conditional type, as shown below:

type NotFunction<T> = T extends Function ? never : T;

This works as follows:

const aFunction = (input: string) => input;
const anObject = { data: 'some data' };
const aString = 'data';

// Error function is not a never
const x: NotFunction<typeof aFunction> = aFunction;

// OK
const y: NotFunction<typeof anObject> = anObject;
const z: NotFunction<typeof aString> = aString;

The only weakness in this is that you have to put the variable on the left side and right side of the statement – although there is safety if you make a mistake such as:

// Error - function is not a string
const x: NotFunction<typeof aString> = aFunction;

Original Answer

You can provide a runtime check using typeof, which although isn’t a compile time check will catch those instances where you forget to execute the function:

function example(input: any) {
    if (typeof input === 'function') {
        alert('You passed a function!');
    }
}

function someFunction() {
    return 1;
}

// Okay
example({ name: 'Zoltán' });
example(1);
example('a string');
example(someFunction());

// Not okay
example(function () {});
example(someFunction);

Why can’t you actually do what you want?

You almost can, because you could use an overload to allow “one of many types”, for example:

class Example {
    someMethod(input: number);
    someMethod(input: string);
    someMethod(input: boolean);
    someMethod(input: any) {

    }
}

Here comes the rub: in order to allow object types, you would have to add an overload signature of someMethod(input: Object); or someMethod(input: {});. As soon as you do this, functions would become allowed, because function inherits from object.

If you could narrow down object to something less general, you could simply add more and more overloads (yikes) for all the types you want to allow.

Leave a Comment