closure-compiler
closure-compiler copied to clipboard
Templated interface not being checked properly
I have a templated interface, a class which implements the interface, and a little driver app file:
ifoo.js
:
goog.module('IFoo');
/**
* @interface
* @template T
*/
class IFoo {
/**
* @param {T=} opt_obj
* @return {T}
*/
foo(opt_obj) {}
};
exports = IFoo;
bar.js
:
goog.module('Bar');
const IFoo = goog.requireType('IFoo');
/**
* @implements {IFoo<Object>}
*/
class Bar {
/**
* @inheritDoc
*/
foo(opt_obj) {
opt_obj = opt_obj || {};
opt_obj['type'] = 'Bar';
return opt_obj;
}
};
exports = Bar;
app.js
:
goog.module('test');
const Bar = goog.require('Bar');
console.log(new Bar().foo());
Error:
./app.js:3: ERROR - [JSC_WRONG_ARGUMENT_COUNT] Function module$exports$Bar.prototype.foo: called with 0 argument(s). Function requires at least 1 argument(s) and no more than 1 argument(s).
console.log(new Bar().foo());
^^^^^^^^^^^^^^^
./bar.js:11: ERROR - [JSC_HIDDEN_INTERFACE_PROPERTY_MISMATCH] mismatch of the foo property on type module$exports$Bar and the type of the property it overrides from interface module$exports$IFoo
original: function(this:module$exports$IFoo, (Object|null)=): (Object|null)
override: function(this:module$exports$Bar, ?): ?
foo(opt_obj) {
^^^
2 error(s), 0 warning(s), 96.5% typed
compiler args:
--dependency_mode PRUNE --summary_detail_level 3 --language_in ECMASCRIPT_2018 --warning_level VERBOSE --jscomp_error accessControls --jscomp_error checkPrototypalTypes --jscomp_error checkRegExp --jscomp_error checkTypes --jscomp_error checkVars --jscomp_error conformanceViolations --jscomp_error const --jscomp_error constantProperty --jscomp_error deprecatedAnnotations --jscomp_error duplicateMessage --jscomp_error es5Strict --jscomp_error externsValidation --jscomp_error functionParams --jscomp_error globalThis --jscomp_error invalidCasts --jscomp_error misplacedTypeAnnotation --jscomp_error missingGetCssName --jscomp_error missingOverride --jscomp_error missingPolyfill --jscomp_error missingProperties --jscomp_error missingProvide --jscomp_error missingRequire --jscomp_error missingReturn --jscomp_error missingSourcesWarnings --jscomp_error moduleLoad --jscomp_error msgDescriptions --jscomp_error nonStandardJsDocs --jscomp_error partialAlias --jscomp_error polymer --jscomp_error strictModuleDepCheck --jscomp_error strictPrimitiveOperators --jscomp_error suspiciousCode --jscomp_error typeInvalidation --jscomp_error undefinedNames --jscomp_error undefinedVars --jscomp_error underscore --jscomp_error unknownDefines --jscomp_error unusedLocalVariables --jscomp_error unusedPrivateMembers --jscomp_error uselessCode --jscomp_error untranspilableFeatures --jscomp_error visibility --jscomp_warning deprecated --jscomp_off reportUnknownTypes --jscomp_off strictCheckTypes --jscomp_off strictMissingProperties --compilation_level ADVANCED --angular_pass true --generate_exports true --output_wrapper (function(){%output%}).call(window); --js_output_file test.min.js --js '!../node_modules/google-closure-library/closure/goog/**test.js' --js '!../node_modules/google-closure-library/third_party/**test.js' --js '../node_modules/google-closure-library/closure/goog/**.js' --js '../node_modules/google-closure-library/third_party/**.js' --js './**.js' --entry_point goog:test --hide_warnings_for /google-closure-library/
This does not occur when processing the same code as a single file or when using goog.provide/require
instead of goog.module
. See this sample repo for an example of each of those along with the above example.
That's interesting. It seems like @inheritDoc
is unable to fill in the correct documentation, presumably because IFoo is being loaded after Bar, which is allowed by the requireType. The current architecture of the TypedScopeBuilder is such that it wants to build up its conception of all the objects eagerly, which means it's really important to do it in the right order. One solution seems like it would be to loosen that requirement, but it's a pretty big overhaul. This particular example could be worked around by just building IFoo before Bar, but in general we can't know with confidence which files to process first.
(going through old issues assigned to me)
Unassigning myself, since I don't currently have bandwidth to work on Closure type system improvements