Object和{}类型有什么区别,何时使用

时间:2018-06-28 05:41:48

标签: typescript

他们很清楚地表明了他们的目的。但这并不满足我作为程序员的要求。对我来说(我才刚刚开始学习Type Script,所以这可能是错误的),他们几乎可以做同一件事。除了可以实现Object(仍然怀疑为什么有人需要这样做)之外,您不能实现{}。 (当然,您也只能新建Object或调用Object.keys和东西。但这在这里无关紧要。)

对于要编写TypeScipt代码的人来说。类型Object和{}有什么区别。为什么类型{}甚至存在?

1 个答案:

答案 0 :(得分:3)

  

您无法实现{}

这根本不是事实。这是允许的:

type Empty = {};

class B implements Empty {

}

当然,这没有什么意义-implements Empty不会为B的用户添加任何信息,也不会对实现施加任何约束。

  

为什么类型{}甚至存在?

如果对名为“交集”和“联合”的类型进行操作,则早晚希望拥有一个类型X,该类型对于任何类型的T都满足等效条件{{1 }}和T | X = TT & X = XX,该类型定义为不具有任何属性。为什么存在?出于相同的原因,存在一个空集。在哪里有用?在任何需要使用具体类型的地方,但不确切知道它可能具有的属性。这是一个示例:

{}

更新

糟糕,事实证明,type BaseEventHandlers<Event extends string> = { [event in Event]: {} }; // in BaseEventHandlers we don't know exact type of data that comes with different event types, // so we have it as {} // it's better than any because any can have unpredictable effect on type checking // it's better than Object because Object has properties with names // that could possibly interfere with our data type EventHandlers<H extends BaseEventHandlers<string>> = { [event in keyof H]: (args: H[event]) => void }; // here we can express a constraint that each event handler // must receive an object of appropriate type // example type UserEvents = { user_added: { name: string }; user_joined_team: { userName: string, teamName: string }; } const userHandlers: EventHandlers<UserEvents> = { // what is checked by the compiler here: // all events have handlers assigned // each handler has correct names for arguments // argument types are inferred from types in `UserEvents` // and do not need to be repeated here user_added: ({ name }) => { }, user_joined_team: ({ userName, teamName }) => { } } 以及诸如{}之类的任何原始类型仍被隐式认为具有string的所有预定义属性-如J所指出的。 Doe,这没有错误:

Object

因此,我的回答只不过是一厢情愿的想法-这就是我想要的const userHandlers: EventHandlers<UserEvents> = { // what is checked by the compiler here: // all events have handlers assigned // each handler has correct names for arguments // argument types are inferred from types in `UserEvents` // and do not need to be repeated here user_added: ({ name, toString }) => { ,但实际上{}{}之间没有什么区别。它们仍然不同:

Object

但是区别是微妙的,我不确定如何在实践中使用它。就个人而言,我更喜欢使用type o = keyof Object; // 'constructor' | 'toString' | ... type e = keyof {}; // never 来表示没有任何属性的类型,而当我需要引用Javascript运行时提供的{}原型时,我会使用Object。因此,差异主要是名义上的,与string and String之间的差异几乎相同。