如何在 TypeScript 中声明仅包含对象而不包含函数的类型
Posted
技术标签:
【中文标题】如何在 TypeScript 中声明仅包含对象而不包含函数的类型【英文标题】:How to declare a type in TypeScript that only includes objects and not functions 【发布时间】:2019-03-12 13:18:18 【问题描述】:是否可以在 TypeScript 中以某种方式定义一个类型,使其只包含对象而不包含函数?
例子:
type T = [name: string]: any // How to modify this to only accepts objects???
const t: T = () => // <- This should not work after modification
感谢您的帮助。
【问题讨论】:
我完全理解你的问题,但在这里只是为了扮演魔鬼的拥护者,如果有人传入一个函数,如果它包含你期望它具有的所有属性会有什么问题? 这是关于重载具有 arity 1 的函数:对象参数的第一个签名,函数参数的第二个签名。在我的代码中,编译器总是采用第一个签名(对于对象和函数),这导致了非预期的类型推断。在我的特殊情况下,解决方案是更改签名声明的顺序。希望我的意思很清楚。意味着:我的问题已经解决了,但是我仍然对上述问题的答案感兴趣......顺便说一句:ExcludeExclude
不起作用,因为在执行它不扩展Function
的断言之前,赋值将函数的类型扩大到T
。
【参考方案1】:
没有完美的方式来引用像“不是函数的对象”这样的类型,因为这需要真正的subtraction types,而这在 TypeScript 中不存在(至少从 3.1 开始)。
一个足够简单的解决方法是查看Function
interface 并描述绝对不是 Function
的东西,但它会匹配您可能运行的大多数非功能对象进入。示例:
type NotAFunction = [k: string]: unknown & ( bind?: never | call?: never );
这意味着“一个带有一些未指定键的对象,它要么缺少bind
属性,要么缺少call
属性”。让我们看看它的表现:
const okayObject: NotAFunction = a: "hey", b: 2, c: true ;
const notOkayObject: NotAFunction = () => ; // error, call is not undefined
很好。
这是一种变通方法而不是简单的解决方案的原因是某些非函数可能同时具有call
和bind
属性,这只是巧合,您会得到一个不受欢迎的错误:
const surprisinglyNotOkay: NotAFunction =
publication: "magazine",
bind: "staples",
call: "867-5309",
fax: null
; // error, call is not undefined
如果您确实需要支持此类对象,您可以将NotAFunction
更改为更复杂并排除更少的非函数,但定义可能总会出错。这取决于你how far you want to go。
希望对您有所帮助。祝你好运!
【讨论】:
LOL 链接很棒以上是关于如何在 TypeScript 中声明仅包含对象而不包含函数的类型的主要内容,如果未能解决你的问题,请参考以下文章