Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type checking and generics

Let's say I have an interface:

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

Which then I'm implementing in several 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;
    }

}

Why TypeScript allows for comparing rectangle and circle?

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

Shouldn't it warn me that I provided incompatible type to circle's equals method?

like image 813
m1gu3l Avatar asked Jun 09 '16 14:06

m1gu3l


People also ask

At what point the generic type checking is done?

Generics provide the type checking at compile time .

What is generic in typing?

Most container types in the Typing module are generic, as they allow you to define what type the contents of the container will be on instantiation. In the case of Dict we can state the type of the key and value.

How do you know if a type is generic?

To examine a generic type and its type parametersGet an instance of Type that represents the generic type. In the following code, the type is obtained using the C# typeof operator ( GetType in Visual Basic, typeid in Visual C++). See the Type class topic for other ways to get a Type object.

Does TypeScript have generics?

TypeScript fully supports generics as a way to introduce type-safety into components that accept arguments and return values whose type will be indeterminate until they are consumed later in your code.


2 Answers

Like JavaScript, TypeScript uses duck typing. So in your example rectangle and circle are identical.

Once these classes add their own implementations the duck typing will fail and the TypeScript compiler will give you errors.

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;
     }

 } 
like image 84
Martin Avatar answered Sep 23 '22 22:09

Martin


Because your Rectangle and Circle are structurally identical, TypeScript treats them as interchangable types (see "duck typing"). Just flesh out your circle and rectangle by adding some mutually incompatible properties to them:

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;}
}

And you'll see the error show up. This is, incidentally, the same reason that you can assign an object literal to a Circle-typed var, as long as it has the right properties:

var c: Circle = {rad: 1, equals: () => true}
like image 28
mk. Avatar answered Sep 20 '22 22:09

mk.