9

Disons que j'ai une interface:vérification de type et génériques

interface Comparable<T> { 
    equals(other:T):boolean 
} 

qui je suis mise en œuvre dans plusieurs classes:

class Rectangle implements Comparable<Rectangle> { 

    equals(other:Rectangle):boolean { 
     // logic 
     return true; 
    } 

} 

class Circle implements Comparable<Circle> { 

    equals(other:Circle):boolean { 
     // logic 
     return true; 
    } 

} 

Pourquoi tapuscrit permet de comparer rectangle et cercle?

let circle:Circle = new Circle(); 
let rectangle:Rectangle = new Rectangle(); 
console.log(circle.equals(rectangle)); 

ne devrait-il me prévenir que je fourni le type incompatible avec de cercle est égal à la méthode?

Répondre

9

Comme JavaScript, TypeScript utilise le typage de canard. Donc, dans votre exemple, le rectangle et le cercle sont identiques. Une fois que ces classes ont ajouté leurs propres implémentations, le typage du canard échouera et le compilateur TypeScript vous donnera des erreurs.

class Rectangle implements Comparable<Rectangle> { 

    width: number; 
    height: number; 

    equals(other:Rectangle): boolean { 
     // logic 
     return true; 
    } 

} 

class Circle implements Comparable<Circle> { 

    diameter: number; 

    equals(other:Circle): boolean { 
     // logic 
     return true; 
    } 

} 
6

Parce que votre rectangle et cercle sont structurellement identiques, tapuscrit les traite comme des types (voir interchangable « frappe de canard »). Il suffit de chair sur votre cercle et le rectangle en ajoutant des propriétés mutuellement incompatibles entre eux:

class Rectangle implements Comparable<Rectangle> { 
    x: number; 
    equals(other:Rectangle):boolean {return true;} 
} 
class Circle implements Comparable<Circle> { 
    rad: number; 
    equals(other:Circle):boolean {return true;} 
} 

Et vous verrez l'erreur apparaissent. C'est, incidemment, la même raison pour laquelle vous pouvez assigner un littéral d'objet à une variable typée Circle, tant qu'elle a les bonnes propriétés:

var c: Circle = {rad: 1, equals:() => true}