(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.