Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
411 views
in Technique[技术] by (71.8m points)

Is there a type in TypeScript for anything except functions?

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 :)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...