diff --git a/src/com/google/javascript/jscomp/GlobalTypeInfo.java b/src/com/google/javascript/jscomp/GlobalTypeInfo.java index e85008e15d5..7e77c408664 100644 --- a/src/com/google/javascript/jscomp/GlobalTypeInfo.java +++ b/src/com/google/javascript/jscomp/GlobalTypeInfo.java @@ -757,8 +757,8 @@ private void checkSuperProperty( } private boolean isValidOverride(JSType localPropType, JSType inheritedPropType) { - FunctionType localFunType = localPropType.getFunTypeIfSingletonObj(); - FunctionType inheritedFunType = inheritedPropType.getFunTypeIfSingletonObj(); + FunctionType localFunType = localPropType.getFunType(); + FunctionType inheritedFunType = inheritedPropType.getFunType(); if (localFunType == null) { return localPropType.isSubtypeOf(inheritedPropType); } else if (inheritedFunType == null) { @@ -773,7 +773,10 @@ private static boolean getsTypeInfoFromParentMethod(PropertyDef pd) { return false; } JSDocInfo jsdoc = NodeUtil.getBestJSDocInfo(pd.defSite); - return jsdoc == null || (jsdoc.isOverride() && !jsdoc.containsFunctionDeclaration()); + if (jsdoc == null) { + return true; + } + return (jsdoc.isOverride() || jsdoc.isExport()) && !jsdoc.containsFunctionDeclaration(); } /** diff --git a/test/com/google/javascript/jscomp/NewTypeInferenceTest.java b/test/com/google/javascript/jscomp/NewTypeInferenceTest.java index f4e51d0c090..ed39d635ab5 100644 --- a/test/com/google/javascript/jscomp/NewTypeInferenceTest.java +++ b/test/com/google/javascript/jscomp/NewTypeInferenceTest.java @@ -4222,7 +4222,7 @@ public void testWarnAboutOverridesNotVisibleDuringGlobalTypeInfo() { GlobalTypeInfo.INVALID_PROP_OVERRIDE); } - public void testInvalidMethodPropertyOverride() { + public void testMethodPropertyOverride() { typeCheck(LINE_JOINER.join( "/** @interface */ function Parent() {}", "/** @type {number} */ Parent.prototype.y;", @@ -4259,6 +4259,46 @@ public void testInvalidMethodPropertyOverride() { "function Bar() {}", "/** @override */", "Bar.prototype.f = function(x) {};")); + + typeCheck(LINE_JOINER.join( + "/** @constructor */", + "function Foo() {}", + "/** @type {function()|undefined} */", + "Foo.prototype.method;", + "/**", + " * @constructor", + " * @extends {Foo}", + " */", + "function Baz() {}", + "/** @export */", + "Baz.prototype.method = function() {};")); + + typeCheck(LINE_JOINER.join( + "/** @constructor */", + "function Foo() {}", + "/** @type {function(number=)} */", + "Foo.prototype.method;", + "/**", + " * @constructor", + " * @extends {Foo}", + " */", + "function Baz() {}", + "/** @export */", + "Baz.prototype.method = function(x) {};", + "(new Baz).method();")); + + typeCheck(LINE_JOINER.join( + "/** @constructor */", + "function Foo() {}", + "/** @type {function(number)|undefined} */", + "Foo.prototype.method;", + "/**", + " * @constructor", + " * @extends {Foo}", + " */", + "function Baz() {}", + "/** @param {number} x */", + "Baz.prototype.method = function(x) {};")); } public void testMultipleObjects() {