The keyword ES6 classes is used to illustrate the concept of specialization:
class SubClass extends BaseClass...
. This indicates that SubClass is a more specialized type.
However, a problem arises when considering
0 | "" | {}
versus 0 | ""
. Instead of narrowing down the possibilities, adding {} expands the options, making false
the correct return value.
To test the idea of "MoreSpecific extends LessSpecific", consider:
0 | "" extends 0 | "" | {} ? true : false
(result: true).
Another perspective involves assignments.
let variable: BaseClass = some_instance_of_SubClass
should be valid. But trying
let myVar1: 0 | "" = value;
fails because none of the union type members permit assigning {}.
In the case of
0 | "" | {} extends 0 | {}
, peculiarities of the empty object type are at play. Various assignments can be made:
let test1: {} = ""
let test2: {} = 34
let test3: {} = {"anything you like": "other than null or undefined"}
(historically for compatibility, see https://github.com/microsoft/TypeScript/issues/44520 “It's a concession to back-compat because { }
was the top type when generics were introduced”)
Since anything other than null or undefined can be assigned to {}
, it follows that 0 | "" | {}
is assignable to {}
and consequently to 0 | {}
. Therefore, the statement ""... extends ..."" holds true.
The inclusion of ""
as an 'extra possibility' is encompassed within the {}
part of 0 | {}
.