google / google/closure-compiler
Template objects cause "unknown type" warning when they shouldn't
- Dominant language
- JavaScript
- Stars
- 7.7k
- Forks
- 1.2k
- Avg merge
- 2d 12h
- Merged PRs (30d)
- 6
Description
There's valid uses (imo) of a template object but the compiler will throw a warning that they shouldn't be used.
Example of what I think is a valid use. There's an `Array>`. The shift function returns T and attempts to return the data field of an element. But the compiler will warn you about this. It doesn't matter that the data field is unknown; I'm not really using it here. All that matters is that it is still T.
``` js
/**
* @struct @final @constructor
* @template T
*/
function MyArray() {
/** @type {!Array>} */
this.arr = [];
}
/** @return {T} */
MyArray.prototype.shift = function() {
let elem = this.arr.shift();
if (elem) {
/*
input0:42: WARNING - Violation: References to object props that are typed as "unknown" are discouraged.
The property "data" on type "MyElement"
return elem.data;
*/
return elem.data;
}
return undefined;
};
/** @param {T} data */
MyArray.prototype.push = function(data) {
this.arr.push(new MyElement(data));
};
/**
* @param {T} data
* @struct @final @constructor
* @template T
*/
function MyElement(data) {
/** @type {T} */
this.data = data;
}
```
[Link to the above.](https://closure-compiler-debugger.appspot.com/#input0%3D%252F**%250A%2520*%2520%2540struct%2520%2540final%2520%2540constructor%250A%2520*%2520%2540template%2520T%250A%2520*%252F%250Afunction%2520MyList%28%29%2520%257B%250A%2520%2520%252F**%2520%2540type%2520%257B%253FMyElement%253CT%253E%257D%2520*%252F%250A%2520%2520this.head%2520%253D%2520null%253B%250A%257D%250A%250A%252F**%2520%2540return%2520%257BT%257Cundefined%257D%2520*%252F%250AMyList.prototype.shift%2520%253D%2520function%28%29%2520%257B%250A%2520%2520if%2520%28this.head%29%2520%257B%250A%2520%2520%2520%2520let%2520elem%2520%253D%2520this.head%253B%250A%2520%2520%2520%2520let%2520data%2520%253D%2520elem.data%253B%250A%2520%2520%2520%2520this.head%2520%253D%2520elem.next%253B%250A%2520%2520%2520%2520elem.next%2520%253D%2520null%253B%250A%2520%2520%2520%2520return%2520data%253B%250A%2520%2520%257D%250A%2520%2520return%2520undefined%253B%250A%257D%253B%250A%250A%252F**%2520%2540param%2520%257BT%257D%2520data%2520*%252F%250AMyList.prototype.push%2520%253D%2520function%28data%29%2520%257B%250A%2520%2520if%2520%28!this.head%29%2520%257B%250A%2520%2520%2520%2520this.head%2520%253D%2520new%2520MyElement%28data%29%253B%250A%2520%2520%2520%2520return%253B%250A%2520%2520%257D%250A%2520%2520let%2520elem%2520%253D%2520this.head%253B%250A%2520%2520while%2520%28elem.next%29%2520elem%2520%253D%2520elem.next%253B%250A%2520%2520elem.next%2520%253D%2520new%2520MyElement%28data%29%253B%250A%257D%253B%250A%250A%252F**%250A%2520*%2520%2540struct%2520%2540final%2520%2540constructor%250A%2520*%2520%2540template%2520T%250A%2520*%252F%250Afunction%2520MyArray%28%29%2520%257B%250A%2520%2520%252F**%2520%2540type%2520%257B!Array%253C!MyElement%253CT%253E%253E%257D%2520*%252F%250A%2520%2520this.arr%2520%253D%2520%255B%255D%253B%250A%257D%250A%250A%252F**%2520%2540return%2520%257BT%257D%2520*%252F%250AMyArray.prototype.shift%2520%253D%2520function%28%29%2520%257B%250A%2520%2520let%2520elem%2520%253D%2520this.arr.shift%28%29%253B%250A%2520%2520if%2520%28elem%29%2520%257B%250A%2520%2520%2520%2520return%2520elem.data%253B%250A%2520%2520%257D%250A%2520%2520return%2520undefined%253B%250A%257D%253B%250A%250A%252F**%2520%2540param%2520%257BT%257D%2520data%2520*%252F%250AMyArray.prototype.push%2520%253D%2520function%28data%29%2520%257B%250A%2520%2520this.arr.push%28new%2520MyElement%28data%29%29%253B%250A%257D%253B%250A%250A%252F**%250A%2520*%2520%2540param%2520%257BT%257D%2520data%250A%2520*%2520%2540struct%2520%2540final%2520%2540constructor%250A%2520*%2520%2540template%2520T%250A%2520*%252F%250Afunction%2520MyElement%28data%29%2520%257B%250A%2520%2520%252F**%2520%2540type%2520%257BT%257D%2520*%252F%250A%2520%2520this.data%2520%253D%2520data%253B%250A%2520%2520%252F**%2520%2540type%2520%257B%253FMyElement%253CT%253E%257D%2520*%252F%250A%2520%2520this.next%2520%253D%2520null%253B%250A%257D%26input1%26conformanceConfig%3D%250Arequirement%253A%2520%257B%250A%2520%2520type%253A%2520CUSTOM%250A%2520%2520java_class%253A%2520'com.google.javascript.jscomp.ConformanceRules%2524BanUnknownThis'%250A%2520%2520error_message%253A%2520'References%2520to%2520%2522this%2522%2520that%2520are%2520typed%2520as%2520%2522unknown%2522%2520are%2520not%2520allowed.%2520See%2520http%253A%252F%252Fgo%252Fclosure-js-conformance%2523unknownThis'%250A%257D%250A%250Arequirement%253A%2520%257B%250A%2520%2520type%253A%2520CUSTOM%250A%2520%2520java_class%253A%2520'com.google.javascript.jscomp.ConformanceRules%2524BanUnresolvedType'%250A%2520%2520error_message%253A%2520'Forward-declared%2520types%2520must%2520be%2520included%2520in%2520the%2520compilation.'%250A%257D%250A%250Arequirement%253A%2520%257B%250A%2520%2520type%253A%2520CUSTOM%250A%2520%2520java_class%253A%2520'com.google.javascript.jscomp.ConformanceRules%2524BanUnknownTypedClassPropsReferences'%250A%2520%2520error_message%253A%2520'References%2520to%2520object%2520props%2520that%2520are%2520typed%2520as%2520%2522unknown%2522%2520are%2520discouraged.'%250A%257D%250A%26externs%26refasterjs-template%26includeDefaultExterns%3D1%26CHECK_SYMBOLS%3D1%26CHECK_TYPES%3D1%26CLOSURE_PASS%3D1%26LANG_IN_IS_ES6%3D1%26MISSING_PROPERTIES%3D1%26PRESERVE_TYPE_ANNOTATIONS%3D1%26PRETTY_PRINT%3D1%26TRANSPILE%3D1)
[Here's](https://closure-compiler-debugger.appspot.com/#input0%3D%252F**%2520%250A%2520*%2520%2540param%2520%257B!Reader%253CT%253E%257D%2520reader%250A%2520*%2520%2540param%2520%257B!Function%253CT%253E%257D%2520callback%250A%2520*%2520%2540template%2520T%250A%2520*%252F%250Afunction%2520readAll%28reader%252C%2520callback%29%2520%257B%250A%2520%2520%28function%2520doRead%28%29%2520%257B%250A%2520%2520%2520%2520reader.read%28%29.then%28result%2520%253D%253E%2520%257B%250A%2520%2520%2520%2520%2520%2520if%2520%28!result.done%29%2520%257B%250A%2520%2520%2520%2520%2520%2520%2520%2520callback%28result.value%29%253B%250A%2520%2520%2520%2520%2520%2520%2520%2520doRead%28%29%253B%250A%2520%2520%2520%2520%2520%2520%257D%250A%2520%2520%2520%2520%257D%29%253B%250A%2520%2520%257D%29%28%29%253B%250A%257D%250A%250A%250A%252F**%2520%250A%2520*%2520%2540param%2520%257Bstring%257D%2520url%2520%250A%2520*%2520%2540param%2520%257B!Function%253C*%253E%257D%2520callback%250A%2520*%252F%250Afunction%2520doFetch%28url%252C%2520callback%29%2520%257B%250A%2520%2520fetch%28url%29.then%28response%2520%253D%253E%2520%257B%250A%2520%2520%2520%2520let%2520reader%2520%253D%2520response.body.getReader%28%29%253B%250A%2520%2520%2520%2520%28function%2520doRead%28%29%2520%257B%250A%2520%2520%2520%2520%2520%2520reader.read%28%29.then%28%28%257Bvalue%252C%2520done%257D%29%2520%253D%253E%2520%257B%250A%2520%2520%2520%2520%2520%2520%2520%2520if%2520%28!done%29%2520%257B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520callback%28value%29%253B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520doRead%28%29%253B%250A%2520%2520%2520%2520%2520%2520%2520%2520%257D%250A%2520%2520%2520%2520%2520%2520%257D%29%253B%250A%2520%2520%2520%2520%257D%29%28%29%253B%250A%2520%2520%257D%29%253B%250A%257D%26input1%26conformanceConfig%3D%250Arequirement%253A%2520%257B%250A%2520%2520type%253A%2520CUSTOM%250A%2520%2520java_class%253A%2520'com.google.javascript.jscomp.ConformanceRules%2524BanUnknownThis'%250A%2520%2520error_message%253A%2520'References%2520to%2520%2522this%2522%2520that%2520are%2520typed%2520as%2520%2522unknown%2522%2520are%2520not%2520allowed.%2520See%2520http%253A%252F%252Fgo%252Fclosure-js-conformance%2523unknownThis'%250A%257D%250A%250Arequirement%253A%2520%257B%250A%2520%2520type%253A%2520CUSTOM%250A%2520%2520java_class%253A%2520'com.google.javascript.jscomp.ConformanceRules%2524BanUnresolvedType'%250A%2520%2520error_message%253A%2520'Forward-declared%2520types%2520must%2520be%2520included%2520in%2520the%2520compilation.'%250A%257D%250A%250Arequirement%253A%2520%257B%250A%2520%2520type%253A%2520CUSTOM%250A%2520%2520java_class%253A%2520'com.google.javascript.jscomp.ConformanceRules%2524BanUnknownTypedClassPropsReferences'%250A%2520%2520error_message%253A%2520'References%2520to%2520object%2520props%2520that%2520are%2520typed%2520as%2520%2522unknown%2522%2520are%2520discouraged.'%250A%257D%250A%26externs%3D%252F**%2520%250A%2520*%2520%2540constructor%2520%250A%2520*%2520%2540template%2520T%250A%2520*%252F%250Afunction%2520Result%28%29%2520%257B%257D%250A%250A%252F**%2520%2540type%2520%257BT%257D%2520*%252F%250AResult.prototype.value%253B%250A%250A%252F**%2520%2540type%2520%257Bboolean%257D%2520*%252F%250AResult.prototype.done%253B%250A%250A%252F**%2520%250A%2520*%2520%2540constructor%2520%250A%2520*%2520%2540template%2520T%250A%2520*%252F%250Afunction%2520Reader%28%29%2520%257B%250A%257D%250A%250A%252F**%250A%2520*%2520%2540return%2520%257B!Promise%253C!Result%253CT%253E%253E%257D%250A%2520*%252F%250AReader.prototype.read%253B%26refasterjs-template%26includeDefaultExterns%3D1%26CHECK_SYMBOLS%3D1%26CHECK_TYPES%3D1%26CLOSURE_PASS%3D1%26LANG_IN_IS_ES6%3D1%26MISSING_PROPERTIES%3D1%26PRESERVE_TYPE_ANNOTATIONS%3D1%26PRETTY_PRINT%3D1%26TRANSPILE%3D1) another example that is basically a templated fetch api. Again I'm not really using the object; I'm just passing it along.
Contributor guide
Assessment
This issue has not been assessed yet.