Skip to content

TS is incorrectly disallowing a variable assignment. #12005

Closed
@DeegC

Description

@DeegC

TypeScript Version: 2.0.3

Code

All of the code in this issue can be run in the playground.

The following gives this compile error: "Type 'EntityInstance' is not assignable to type 'EntityInstance'."

export class EntityInstance {
    public deleted = false;
    private children = new EntityArray<EntityInstance>();

    getChildren(): EntityArray<EntityInstance> {
        return this.children;
    }
}

export class ExtendedInstance extends EntityInstance {
    public anotherProperty = true;

    getChildren(): EntityArray<ExtendedInstance> {
        return super.getChildren() as EntityArray<ExtendedInstance>;
    }
}

let ei = new ExtendedInstance();
ei.getChildren()[0].anotherProperty = false;

export class EntityArray<EntityInstance> extends Array<EntityInstance> {

    delete(index?: number) {
        let ei = new EntityInstance();
        ei = this.splice( index, 1 )[0];
        ei.deleted = true;
    }
}

Expected behavior:

This should be allowed. It appears that TS thinks that EntityInstance as specified in "EntityArray" is a different type from EntityInstance. The former EntityInstance doesn't appear to have type information. For example, if I rewrite the delete() as follows there is an error because TS doesn't know about the 'deleted' property:

    delete(index?: number) {
        let ei = this.splice( index, 1 )[0];
        ei.deleted = true;
    }

Actual behavior:

TS raises compile error.

More notes:

I could define EntityArray without the <> (which then correctly determines the types in delete) but then I lose type information when I call ExtendedInstance.getChildren(). For example, the above code fails when rewitten as:

export class EntityInstance {
    public deleted = false;
    private children = new EntityArray();

    getChildren(): EntityArray {
        return this.children;
    }
}

export class ExtendedInstance extends EntityInstance {
    public anotherProperty = true;

    getChildren(): EntityArray {
        return super.getChildren();
    }
}

let ei = new ExtendedInstance();
ei.getChildren()[0].anotherProperty = false;

export class EntityArray extends Array<EntityInstance> {

    delete(index?: number) {
        let ei = new EntityInstance();
        ei = this.splice( index, 1 )[0];
        ei.deleted = true;
    }
}

I can get by the original error by casting to in the delete method but who wants to do that in Typescript?

delete(index?: number) { 
    let ei = this.splice( index, 1 )[0] as any; 
    ei.deleted = true; 
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    QuestionAn issue which isn't directly actionable in code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions