Skip to content

Generic parameters constrained by polymorphic types allow unsafe operations but are not widened on return positions #7933

Closed
@malibuzios

Description

@malibuzios

TypeScript Version:

1.9.0-dev.20160405

Code

class Animal {
    name: string;
}

class Dog extends Animal {
    bark() {};
}

class Cat extends Animal {
    meow() {};
}

class Box<V> {
    item: V;
}

function f<T extends Box<Animal>>(box: T) {
    box.item = new Cat(); // <-- This is perfectly valid and allowed by the constraint
    return box; // <-- The returned type is T
}

let result = f(new Box<Dog>()); // Type of 'result' is inferred as Box<Dog>
result.item.bark(); // <-- No compilation error. Run-time error..

Expected behavior:
Type of result should be inferred as Box<Animal>.
result.item.bark(); should give a compilation error.

Actual behavior:
Type of result is inferred as Box<Dog>.
result.item.bark(); does not error at compile-time but does error at run-time.

Comments:
Type of box should be widened from T to Box<Animal> within the body of the function, as there is no (current) way to ensure the members of box are not reassigned with types incompatible to the ones specified in T. The return type should therefore be Box<Animal> and not T.

[Edits: rewritten main example, heavily shortened and removed unneeded sections]

Metadata

Metadata

Assignees

No one assigned

    Labels

    By DesignDeprecated - use "Working as Intended" or "Design Limitation" instead

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions