Given the following code:
function testMenu1() as Menu2 { var menu = new CheckboxMenu({ :title => "My CheckboxMenu" }); unsafeAddItem(menu, new MenuItem("hello", null, :hello, null)); return menu; } function testMenu2() as Menu2 { var menu = new CheckboxMenu({ :title => "My CheckboxMenu" }); menu.addItem(new MenuItem("hello", null, :hello, null)); return menu; } function unsafeAddItem(menu as Menu2, item as MenuItem) as Void { menu.addItem(item); }
the type checker correctly complains that testMenu2 is trying to add a MenuItem to a CheckboxMenu. But it's quite happy that testMenu1 does exactly the same thing, just using a helper to do so. Both functions crash at runtime.
The problem here is that unsafeAddItem should fail to type check, because all the type checker knows is that menu is an instance of Menu2 - which includes CheckboxMenu, and so calling addItem with a MenuItem might be an error. But the real problem is that addItem has a covariant argument, so that although "CheckboxMenu instanceof Menu2", you can't use it as a Menu2, and that means that the type checker can't really do its job.
I don't see a good solution here; ideally, CheckboxMenu and Menu2 would both derive from a common base class, which doesn't include addItem (or updateItem) in its interface. That way, unsafeAddItem would be correct (since you couldn't pass it a CheckboxMenu). But thats likely to break existing code (or at least, make the type checker report errors for it).