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