(Originally wanting to open a bug report in the issue tracker of the TypeScript repo, I realized that I asked too many questions, so I am opening a question here before the bug report.)
Playground link with relevant code
type Foo0 = {} extends Record<string, unknown> ? true : false;
// ^? [type Foo0 = true]
type Foo1 = Record<string, unknown> extends {} ? true : false;
// ^? [type Foo1 = true]
type Bar0 = {} extends object ? true : false;
// ^? [type Bar0 = true]
type Bar1 = object extends {} ? true : false;
// ^? [type Bar1 = true]
type Baz0 = Record<string, unknown> extends object ? true : false;
// ^? [type Baz0 = true]
type Baz1 = object extends Record<string, unknown> ? true : false;
// ^? [type Baz1 = false]
Edited Question: I guess I've got the point. In Foo0 and Bar0, {} represents “an empty object (a record without any values)”, so it's assignable to both object (which represents “any non-primitive”) and Record<string, unknown> (which is equivalent to { [key: string]: unknown }). On the other hand, {} in Foo1 and Bar1 represents “any non-nullish value”, thus both object and Record<string, unknown> are assignable to it. So I guess my question would become:
Why
{}represents two different things? Is it intentional? If it's due to historical reasons, is there any chance that these two things get separated out?
Do point them out if I got something wrong.