Bug Description
When a bare template parameter T is inferred from an object literal, Closure Compiler appears to bind T to the exact anonymous object-literal type of that expression, instead of widening it to a structural record type.
As a result, a later argument with the same structural shape is rejected, even though:
- the same shape is assignable through typedef {{...}}
- the same shape is assignable through inline record annotations like {{a: string}}
Small repro
// a.js
/** @template T */
class Box {
/** @param {!T} value */
constructor(value) {}
/** @param {!T} other */
same(other) {}
}
new Box({a: "a"}).same({a: "a"});
java -jar bazel-bin/compiler_uberjar_deploy.jar \
--compilation_level=ADVANCED \
--language_in=ECMASCRIPT_NEXT \
--language_out=ECMASCRIPT_NEXT \
--jscomp_error=checkTypes a.js
a.js:10:23: ERROR - [JSC_TYPE_MISMATCH] actual parameter 1 of Box.prototype.same does not match formal parameter
found : {a: string}
required: {a: string}
10| new Box({a: "a"}).same({a: "a"});
Bug Description
When a bare template parameter T is inferred from an object literal, Closure Compiler appears to bind T to the exact anonymous object-literal type of that expression, instead of widening it to a structural record type.
As a result, a later argument with the same structural shape is rejected, even though:
Small repro