closure-compiler
closure-compiler copied to clipboard
Recursive record types fail silently, documentation lacks
Recursive record types are seemingly not supported. However, it is not directly documented (that I know of). The behavior of the compiler is that it assigns unknown
type to the recursive part.
/**
* @typedef {{ name: string, next: Car }} // should produce error, but instead it treats `.next` as `?` (unknown type)
*/
var Car;
/**
* @type {Car}
*/
const car = {
name: 'BMW',
next: {
name: 'Audi',
}
}
In this example the .next
attribute becomes unknown
. This is not ideal, it is by no means obvious that recursion is not supported. The compiler should raise an error/warning saying that recursion in record types is not supported.
It would also be useful to add a section in the wiki about the correct syntax for recursive types.
There is a mention in #2011 that they can be implemented using the @record
keyword. It would be helpful to add this to wiki as well.
Compiler Version: v20221102
Build command:
java -jar ./scripts/closureCompiler.jar \
--entry_point=./src/js/index.js \
--js=./src/**.js \
--dependency_mode=PRUNE \
--warning_level=VERBOSE \
--js_output_file=./dist/bundle.js \
--module_resolution=WEBPACK \
--compilation_level=ADVANCED \
--jscomp_error=checkDebuggerStatement \
--jscomp_error=unusedLocalVariables \
--jscomp_error=reportUnknownTypes \
--jscomp_error=strictCheckTypes;
More than record types, I think the problem is that typedef
fails silently. They aren't supposed to be recursive, as they're used define an alias for an existing type. So we should probably warn.
/**
* @typedef {{ name: string, next: Car }}
*/
var Car;
The @type
using recursive types does report:
/**
* @type {{ name: string, next: Car }} ----> WARNING - [JSC_UNRECOGNIZED_TYPE_ERROR]
*/
var Car;