Typescript 类型对象和{}之间有什么区别?什么时候使用它

Typescript 类型对象和{}之间有什么区别?什么时候使用它,typescript,Typescript,他们很清楚他们的目的是什么。但作为一名程序员,这并不能让我满意。对我来说(我刚刚开始学习类型脚本,所以这可能是错误的),他们可以也不能做几乎相同的事情。除了您可以实现对象(仍然怀疑为什么有人需要这样做),但您不能实现{}。(当然,您也只能创建新对象或调用Object.key等,但这与此无关) 所以对于那些将要编写TypeScipt代码的人来说。类型对象和{}之间的区别是什么。为什么类型{}甚至存在 您无法实现{} 这根本不是事实。这是允许的: type Empty = {}; class B

他们很清楚他们的目的是什么。但作为一名程序员,这并不能让我满意。对我来说(我刚刚开始学习类型脚本,所以这可能是错误的),他们可以也不能做几乎相同的事情。除了您可以实现对象(仍然怀疑为什么有人需要这样做),但您不能实现{}。(当然,您也只能创建新对象或调用Object.key等,但这与此无关)

所以对于那些将要编写TypeScipt代码的人来说。类型对象和{}之间的区别是什么。为什么类型{}甚至存在

您无法实现{}

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

type Empty = {};

class B implements Empty {

}
当然,这没有多大意义-
实现空
不会为
B
的用户添加任何信息,也不会对实现添加任何约束

为什么类型{}甚至存在

如果您对名为“交集”和“并集”的类型进行操作,那么您迟早会想要一个类型
X
,对于任何类型
T
,该类型都满足等价性
T | X=T
T&X=X
。这个
X
{}
,一种定义为没有任何属性的类型。它为什么存在?出于同样的原因,存在一个空集。它在哪里有用?当您需要一个具体的类型,但不知道它可能具有哪些属性时,可以在任何地方使用。以下是一个例子:

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 }) => {

    }
}
所以我的答案只不过是一厢情愿——这就是我想要的
{}
,但实际上
{}
对象
之间几乎没有什么区别。它们仍然不同:

type o = keyof Object; // 'constructor' | 'toString' | ...

type e = keyof {}; // never

但差别是微妙的,我不确定如何在实践中使用它。就我个人而言,我更喜欢使用
{}
来表示没有任何属性的类型,当我需要参考Javascript运行时提供的
对象
原型时,我更喜欢使用
对象
来表示类型。因此,差异主要是概念上的,与之间的差异几乎相同。

这将有所帮助:我认为这个问题的评论很有启发性,但不确定它在这里有多重要:对于
constuserhandlers
,我更改了添加到
中的user\u,user\u添加:({name,toString})=>{}
,但它没有给我错误。
type o = keyof Object; // 'constructor' | 'toString' | ...

type e = keyof {}; // never