Skip to content
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

Inherited types in callback functions #222

Closed
arknave opened this issue Jul 24, 2014 · 3 comments
Closed

Inherited types in callback functions #222

arknave opened this issue Jul 24, 2014 · 3 comments
Labels
By Design Deprecated - use "Working as Intended" or "Design Limitation" instead

Comments

@arknave
Copy link

arknave commented Jul 24, 2014

Typescript is too lenient when accepting sub-classes in inherited types. For example:

interface Base {
    baseField: string;
}
interface Child extends Base {
    childField: number;
}

var test = function (callbackfn: (value: Base) => void): void {
    callbackfn({baseField: ""});
};

var callTest = function() {
    test(function (value: Child) {
        console.log(value.childField);
    });
};

should not compile, as callbackfn requires a Base, not a Child. It is not correct that value is a child. If Child does not extend Base, then this causes a compile error as expected. However, if we add no explicit hierarchy between the classes, but change the example to

interface Base {
    baseField: string;
}
interface Child {
    baseField: string;    
    childField: number;
}

var test = function (callbackfn: (value: Base) => void): void {
    callbackfn({baseField: ""});
};

var callTest = function() {
    test(function (value: Child) {
        console.log(value.childField);
    });
};

then the code still compiles. Both of these are errors that should hopefully be caught at compile time. It looks like typescript only checks to see if a callback parameter is valid if the classes have common members. This should be changed to a subset.

@basarat
Copy link
Contributor

basarat commented Jul 24, 2014

@arknave this is by design. It allows you to type event handler arguments easily e.g. e:MouseEvent when the original signature is only e:Event. Its allowed as long as a is subtype of b or b is subtype of a

@basarat
Copy link
Contributor

basarat commented Jul 24, 2014

@arknave
Copy link
Author

arknave commented Jul 24, 2014

Man, even the documentation agrees its unsound. Thanks for the link, not sure why I couldn't find it.

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
Projects
None yet
Development

No branches or pull requests

3 participants