typescript - Varför ger extends false när man jämför två interface?


Bakgrund

Jag har försökt få en bättre förståelse för hur extends fungerar. Jag läste den här utmärkta artikeln som beskriver A extends B som att det betyder,

'A är en övermängd av B'

Eller

'A är en möjligen mer specifik version av B'

Jag läste också ett SO-svar (som jag inte längre kan hitta) där författaren beskriver extends som att det betyder,

går in i

Allt detta hjälpte mig att förstå.

Problem

Jag satte ihop några exempel (i TS-lekplatsen) med en hjälptyp för att se själv, men hittade ett fall som jag inte förväntade mig skulle returnera false.

type DoesExtend<A, B> = A extends B ? true : false;


interface MyInterface<A, B = void> {
    doSomething(input: A): B extends void ? A : A | B;
}

class MyClass1 implements MyInterface<string> {
    doSomething(input: string): string {
        return input;
    }
}

class MyClass2 implements MyInterface<string, number> {
    doSomething(input: string): string | number {
        return input;
    }
}

Följande jämförelser gav alla det jag förväntade mig,

DoesExtend<MyClass1, MyClass2> //true
DoesExtend<MyClass2, MyClass1> //false

DoesExtend<MyClass1, MyInterface<string>> // true
DoesExtend<MyInterface<string>, MyClass1> // true
DoesExtend<MyClass1, MyInterface<string, number>> // true
DoesExtend<MyInterface<string, number>, MyClass1> // false

DoesExtend<MyClass2, MyInterface<string>> // false
DoesExtend<MyInterface<string>, MyClass2> // true
DoesExtend<MyClass2, MyInterface<string, number>> // true
DoesExtend<MyInterface<string, number>, MyClass2> // true

Men när man jämförde MyInterface med MyInterface var ett resultat oväntat,

DoesExtend<MyInterface<string>, MyInterface<string, number>> // false - but i expected true?
DoesExtend<MyInterface<string, number>, MyInterface<string>> // false
DoesExtend<MyInterface<string, number>, MyInterface<string, number>> // true
DoesExtend<MyInterface<string, number>, MyInterface<string, number | Function>> // true

Fråga

Så med tanke på att följande är sant,

DoesExtend<MyClass1, MyClass2>
DoesExtend<MyClass1, MyInterface<string, number>>
DoesExtend<MyInterface<string>, MyClass2>

kan någon vänligen förklara varför följande - som för mig skulle verka motsvara exemplen ovan och som jag förväntade mig vara sant - är falskt?

DoesExtend<MyInterface<string>, MyInterface<string, number>>