Is there a type in TypeScript for anything except functions?

typescript

Solution

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.

Problem

I would like to express that a paremeter should be an object or a simple value type (number, bool, string, etc.), but not a function. If I use `Object`, the compiler let's me to assign a function. ``` var test: Object = () => "a"; ``` If I use `any`, the same result of course too. Is there a type or trick which can help me out in this case? My underlying goal is to garantee safety when using Knockout observables, so that I don't forget those little paranthesis to unwrap them :)

Original source