1

They made it really clear what their purpose are. But that doesn't satisfy me as a programmer. To me (I'm just started learning Type Script, so this might be wrong), they can and can't do almost the same thing. Except that you can implement Object (still doubt why anyone ever need to do this) but you can't implement {}. (Of course you can also only new Object or call Object.keys and stuff. But that's irrelevant here).

So to people whom going to write TypeScipt code. What is the difference between type Object and {}. Why type {} even exist?

W.H
  • 1,838
  • 10
  • 24
  • 2
    This will help: https://stackoverflow.com/a/28795689/3783478 – Rajesh Jun 28 '18 at 06:46
  • 1
    I thought this issue-comment was enlightening, not sure how relevant it is here though: https://github.com/Microsoft/TypeScript/issues/16971#issuecomment-313417452 – ippi Jun 28 '18 at 06:49

1 Answers1

3

you can't implement {}

This is simply not true. This is allowed:

type Empty = {};

class B implements Empty {

}

Granted, it does not make much sense - implements Empty does not add any information for the users of B, and does not add any constraint on the implementation.

Why type {} even exist?

If you have operations on types named "intersection" and "union", you will sooner or later want to have a type X that, for any type T, satisfies the equivalences T | X = T and T & X = X. This X is {}, a type which is defined not to have any properties. Why does it exist? For the same reason an empty set exists. Where it can be useful? Anywhere when you need to have a concrete type, but don't know exactly which properties it could have. Here is one example:

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

    }
}

Update

Oops, it turns out that {}, as well as any primitive type like string, is still implicitly considered to have all predefined properties of an Object - as noted by J.Doe, this gives no error:

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

So my answer is little more than wishful thinking - that's what I want {} to be, but in reality there is very little difference between {} and Object. They are still different:

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

type e = keyof {}; // never

but the difference is subtle and I'm not sure how it can be used in practice. Personally, I prefer to use {} to represent type without any properties, and Object when I need to refer to Object prototype provided by Javascript runtime. So the difference is mostly notional, pretty much the same way as the difference between string and String.

artem
  • 46,476
  • 8
  • 74
  • 78
  • for `const userHandlers`, I changed user_added to this `user_added: ({ name, toString }) => { }` but it gives me no error. – W.H Jun 28 '18 at 07:01