因此,根据您的评论,您想要“不是函数的对象”之类的东西。 TypeScript 目前没有negated types,因此没有简洁的方式来表达“不是函数”。根据您的用例,您可能只想耸耸肩继续前进。
或者,您可能会尝试通过变通方法强制 TypeScript 屈服于您的意愿。
最简单的解决方法是找到一些函数始终具有的属性,并声明您的类型具有不兼容的同名可选属性。例如:
type NoCall = { call?: number | string | boolean | null | undefined, [k: string]: any };
const okay: NoCall = { a: 4 }; // okay
const err: NoCall = () => 2; // error
缺点是您将无法验证某些合法的非函数(在上述情况下,{call: ()=>0} 不是函数,但无法验证为 NoCall)。但是,对于您的用例来说,可能有些误报是可以接受的?
无论如何,根据标准库lib.es5.d.ts 来检查属性名称的合理选择是apply、call、bind、arguments 和caller。
如果您不喜欢放弃其中一个名称,您可以选择使用global augmentation 将幻像属性添加到Function 接口:
declare global {
interface Function {
'*FunctionsHaveThis*': true
}
}
type ObjNotFunction = { '*FunctionsHaveThis*'?: never, [k: string]: any };
const okay: ObjNotFunction = { a: 4 }; // okay
const err: ObjNotFunction = () => 2; // error
这会降低属性名称冲突的可能性,但会污染全局命名空间,并使这种解决方法变得不那么简单。
另一种解决方法是使用 trick 和 conditional types 来防止函数作为参数传递给另一个函数:
function noFunctionsPlease<T extends object>(t: T & (T extends Function ? never : T)) {
// do something with t
}
noFunctionsPlease({ a: 4 }); // okay
noFunctionsPlease(() => 2); // error
t 的类型或多或少准确地说是“不是函数的对象”,但它只能表示为函数参数。
希望其中一个对您有所帮助或让您了解如何(或是否)继续进行。祝你好运!