Skip to content

is this a Generic bug? #3275

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Paul-Lo opened this issue May 27, 2015 · 2 comments
Closed

is this a Generic bug? #3275

Paul-Lo opened this issue May 27, 2015 · 2 comments
Labels
By Design Deprecated - use "Working as Intended" or "Design Limitation" instead Canonical This issue contains a lengthy and complete description of a particular problem, solution, or design Question An issue which isn't directly actionable in code

Comments

@Paul-Lo
Copy link

Paul-Lo commented May 27, 2015

consider the following class.

class GenericPractice<T>{
    private entity: T;
    constructor(entity: T) {
        this.entity = entity;
    }

    public add(item: T): string {
        return item.toString();
    }

}
class CouponInfo {
    public toString(): string {
        return "couponInfo";
    }
}
class Snake{
}

 var genericPractice = new GenericPractice<CouponInfo>(new CouponInfo());
genericPractice.add(new Snake("Sammy the Python")));

theoretically, the above last line:

genericPractice.add(new Snake("Sammy the Python")));

should have compile time error since the generic of class GenericPractice should only allow CouponInfo in method add, not Snake.

However, the compile still passes which violates the fundamental concept of generic.
is this a bug?

@DanielRosenwasser DanielRosenwasser added By Design Deprecated - use "Working as Intended" or "Design Limitation" instead Canonical This issue contains a lengthy and complete description of a particular problem, solution, or design labels May 27, 2015
@DanielRosenwasser
Copy link
Member

Note: I assume that you didn't mean to supply an argument to the Snake constructor.

This has to do with TypeScript having a predominantly structural type system. For that reason, the following works:

class CouponInfo {
    public toString(): string {
        return "couponInfo";
    }
}

class Snake {
}

// No problem with either of these.
var x: CouponInfo = new Snake();
var y: Snake = new CouponInfo();

Since instances of Snake have the same apparent members as those of CouponInfo, Snakes are assignable to CouponInfos.

Thus when add expects a CouponInfo, you can give it a Snake.

If you want to avoid this, you can add a private "tag" member in each class. Privates are not compared in a structural manner, regardless of their name and type.

class CouponInfo {
    // Introduced a tag here.
    private couponTag: {};

    public toString(): string {
        return "couponInfo";
    }
}

class Snake {
    // Introduced a tag here.
    private snakeTag: {};
}

var genericPractice = new GenericPractice(new CouponInfo());

// Now all of these cause errors.
genericPractice.add(new Snake());
var x: CouponInfo = new Snake();
var y: Snake = new CouponInfo();

Hope that answers your question!

@Paul-Lo
Copy link
Author

Paul-Lo commented May 27, 2015

Thanks for the informative and comprehensive answer!

@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
By Design Deprecated - use "Working as Intended" or "Design Limitation" instead Canonical This issue contains a lengthy and complete description of a particular problem, solution, or design Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

2 participants