他们很清楚地表明了他们的目的。但这并不满足我作为程序员的要求。对我来说(我才刚刚开始学习Type Script,所以这可能是错误的),他们几乎可以做同一件事。除了可以实现Object(仍然怀疑为什么有人需要这样做)之外,您不能实现{}。 (当然,您也只能新建Object或调用Object.keys和东西。但这在这里无关紧要。)
对于要编写TypeScipt代码的人来说。类型Object和{}有什么区别。为什么类型{}甚至存在?
答案 0 :(得分:3)
您无法实现{}
这根本不是事实。这是允许的:
type Empty = {};
class B implements Empty {
}
当然,这没有什么意义-implements Empty
不会为B
的用户添加任何信息,也不会对实现施加任何约束。
为什么类型{}甚至存在?
如果对名为“交集”和“联合”的类型进行操作,则早晚希望拥有一个类型X
,该类型对于任何类型的T
都满足等效条件{{1 }}和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 }) => {
}
}
以及诸如{}
之类的任何原始类型仍被隐式认为具有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
之间的差异几乎相同。