google / google/closure-compiler
Cannot use properties as types
- Dominant language
- JavaScript
- Stars
- 7.7k
- Forks
- 1.2k
- Avg merge
- 2d 12h
- Merged PRs (30d)
- 6
Description
```
class Parent {}
const Obj = {};
Obj.Alias = Parent;
class Child extends Obj.Alias {} // Bad type annotation. Unknown type Obj.Alias
```
[Link](https://closure-compiler-debugger.appspot.com/#input0%3Dclass%2520Parent%2520%257B%257D%250Aconst%2520Obj%2520%253D%2520%257B%257D%253B%250AObj.Alias%2520%253D%2520Parent%253B%250Aclass%2520Child%2520extends%2520Obj.Alias%2520%257B%257D%26input1%26conformanceConfig%26externs%26refasterjs-template%26includeDefaultExterns%3Dtrue%26CHECK_SYMBOLS%3Dtrue%26MISSING_PROPERTIES%3Dtrue%26TRANSPILE%3Dtrue%26CHECK_TYPES%3Dtrue%26CLOSURE_PASS%3Dtrue%26PRESERVE_TYPE_ANNOTATIONS%3Dtrue%26PRETTY_PRINT%3Dtrue)
The error here stems from the `@extends {Obj.Alias}` in the transpiled code.
This causes a bug in ES6 module rewriting. If a class is exported directly then things are fine:
```
export class Parent {
static staticFunction() { return 'Parent.staticFunction'; }
}
```
```
import { Parent } from './input0';
class Child extends Parent {}
```
[Link](https://closure-compiler-debugger.appspot.com/#input0%3Dexport%2520class%2520Parent%2520%257B%250A%2520%2520static%2520staticFunction()%2520%257B%2520return%2520'Parent.staticFunction'%253B%2520%257D%250A%257D%26input1%3Dimport%2520%257B%2520Parent%2520%257D%2520from%2520'.%252Finput0'%253B%250A%250Aclass%2520Child%2520extends%2520Parent%2520%257B%257D%26conformanceConfig%26externs%26refasterjs-template%26includeDefaultExterns%3Dtrue%26CHECK_SYMBOLS%3Dtrue%26MISSING_PROPERTIES%3Dtrue%26TRANSPILE%3Dtrue%26CHECK_TYPES%3Dtrue%26CLOSURE_PASS%3Dtrue%26PRESERVE_TYPE_ANNOTATIONS%3Dtrue%26PRETTY_PRINT%3Dtrue)
Note the type annotation of the extends ends up being Parent$$module$input0.
But if we export using export specs there's an error.
```
class Parent {
static staticFunction() { return 'Parent.staticFunction'; }
}
export { Parent };
```
```
import { Parent } from './input0';
class Child extends Parent {} // Bad type annotation. Unknown type module$input0.Parent
```
[Link](https://closure-compiler-debugger.appspot.com/#input0%3Dclass%2520Parent%2520%257B%250A%2520%2520static%2520staticFunction()%2520%257B%2520return%2520'Parent.staticFunction'%253B%2520%257D%250A%257D%250A%250Aexport%2520%257B%2520Parent%2520%257D%253B%26input1%3Dimport%2520%257B%2520Parent%2520%257D%2520from%2520'.%252Finput0'%253B%250A%250Aclass%2520Child%2520extends%2520Parent%2520%257B%257D%26conformanceConfig%26externs%26refasterjs-template%26includeDefaultExterns%3Dtrue%26CHECK_SYMBOLS%3Dtrue%26MISSING_PROPERTIES%3Dtrue%26TRANSPILE%3Dtrue%26CHECK_TYPES%3Dtrue%26CLOSURE_PASS%3Dtrue%26PRESERVE_TYPE_ANNOTATIONS%3Dtrue%26PRETTY_PRINT%3Dtrue)
Note the type annotation is now module$input0.Parent.
Appears to be an OTI only bug, but seems pretty important.
Contributor guide
Assessment
This issue has not been assessed yet.