新功能答案
2018 年 11 月添加 - 因为条件类型现在很流行!
条件类型为此提供了一个可能的解决方案,因为您可以创建一个NotFunction
条件类型,如下图:
type NotFunction<T> = T extends Function ? never : T;
其工作原理如下:
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;
唯一的弱点是您必须将变量放在语句的左侧和右侧 - 尽管如果您犯了错误,例如以下错误,也是安全的:
// Error - function is not a string
const x: NotFunction<typeof aString> = aFunction;
原答案
您可以使用提供运行时检查typeof
,虽然不是编译时检查,但会捕获您忘记执行该函数的那些实例:
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);
为什么你不能真正做你想做的事?
您几乎可以,因为您可以使用重载来允许“多种类型之一”,例如:
class Example {
someMethod(input: number);
someMethod(input: string);
someMethod(input: boolean);
someMethod(input: any) {
}
}
问题来了:为了允许对象类型,您必须添加一个重载签名someMethod(input: Object);
or someMethod(input: {});
。一旦你这样做了,函数就会被允许,因为函数继承自对象。
如果你能缩小范围object
对于不太通用的东西,您可以简单地为您想要允许的所有类型添加越来越多的重载(哎呀)。