Skip to content

Commit 4bba6ee

Browse files
author
Andy
authored
Support accessing enum types from JSDoc (#18703)
1 parent 0b7dd5a commit 4bba6ee

File tree

4 files changed

+72
-26
lines changed

4 files changed

+72
-26
lines changed

src/compiler/checker.ts

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5252,6 +5252,10 @@ namespace ts {
52525252
}
52535253

52545254
function getDeclaredTypeOfSymbol(symbol: Symbol): Type {
5255+
return tryGetDeclaredTypeOfSymbol(symbol) || unknownType;
5256+
}
5257+
5258+
function tryGetDeclaredTypeOfSymbol(symbol: Symbol): Type | undefined {
52555259
if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
52565260
return getDeclaredTypeOfClassOrInterface(symbol);
52575261
}
@@ -5270,7 +5274,7 @@ namespace ts {
52705274
if (symbol.flags & SymbolFlags.Alias) {
52715275
return getDeclaredTypeOfAlias(symbol);
52725276
}
5273-
return unknownType;
5277+
return undefined;
52745278
}
52755279

52765280
// A type reference is considered independent if each type argument is considered independent.
@@ -6872,17 +6876,6 @@ namespace ts {
68726876
return type;
68736877
}
68746878

6875-
/**
6876-
* Get type from reference to named type that cannot be generic (enum or type parameter)
6877-
*/
6878-
function getTypeFromNonGenericTypeReference(node: TypeReferenceType, symbol: Symbol): Type {
6879-
if (node.typeArguments) {
6880-
error(node, Diagnostics.Type_0_is_not_generic, symbolToString(symbol));
6881-
return unknownType;
6882-
}
6883-
return getDeclaredTypeOfSymbol(symbol);
6884-
}
6885-
68866879
function getTypeReferenceName(node: TypeReferenceType): EntityNameOrEntityNameExpression | undefined {
68876880
switch (node.kind) {
68886881
case SyntaxKind.TypeReference:
@@ -6919,24 +6912,34 @@ namespace ts {
69196912
return type;
69206913
}
69216914

6922-
if (symbol.flags & SymbolFlags.Value && isJSDocTypeReference(node)) {
6923-
// A jsdoc TypeReference may have resolved to a value (as opposed to a type). If
6924-
// the symbol is a constructor function, return the inferred class type; otherwise,
6925-
// the type of this reference is just the type of the value we resolved to.
6926-
const valueType = getTypeOfSymbol(symbol);
6927-
if (valueType.symbol && !isInferredClassType(valueType)) {
6928-
const referenceType = getTypeReferenceTypeWorker(node, valueType.symbol, typeArguments);
6929-
if (referenceType) {
6930-
return referenceType;
6931-
}
6915+
// Get type from reference to named type that cannot be generic (enum or type parameter)
6916+
const res = tryGetDeclaredTypeOfSymbol(symbol);
6917+
if (res !== undefined) {
6918+
if (typeArguments) {
6919+
error(node, Diagnostics.Type_0_is_not_generic, symbolToString(symbol));
6920+
return unknownType;
69326921
}
6922+
return res;
6923+
}
69336924

6934-
// Resolve the type reference as a Type for the purpose of reporting errors.
6935-
resolveTypeReferenceName(getTypeReferenceName(node), SymbolFlags.Type);
6936-
return valueType;
6925+
if (!(symbol.flags & SymbolFlags.Value && isJSDocTypeReference(node))) {
6926+
return unknownType;
6927+
}
6928+
6929+
// A jsdoc TypeReference may have resolved to a value (as opposed to a type). If
6930+
// the symbol is a constructor function, return the inferred class type; otherwise,
6931+
// the type of this reference is just the type of the value we resolved to.
6932+
const valueType = getTypeOfSymbol(symbol);
6933+
if (valueType.symbol && !isInferredClassType(valueType)) {
6934+
const referenceType = getTypeReferenceTypeWorker(node, valueType.symbol, typeArguments);
6935+
if (referenceType) {
6936+
return referenceType;
6937+
}
69376938
}
69386939

6939-
return getTypeFromNonGenericTypeReference(node, symbol);
6940+
// Resolve the type reference as a Type for the purpose of reporting errors.
6941+
resolveTypeReferenceName(getTypeReferenceName(node), SymbolFlags.Type);
6942+
return valueType;
69406943
}
69416944

69426945
function getTypeReferenceTypeWorker(node: TypeReferenceType, symbol: Symbol, typeArguments: Type[]): Type | undefined {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
=== /a.ts ===
2+
export enum E { A }
3+
>E : Symbol(E, Decl(a.ts, 0, 0))
4+
>A : Symbol(E.A, Decl(a.ts, 0, 15))
5+
6+
=== /b.js ===
7+
import { E } from "./a";
8+
>E : Symbol(E, Decl(b.js, 0, 8))
9+
10+
/** @type {E} */
11+
const e = E.A;
12+
>e : Symbol(e, Decl(b.js, 2, 5))
13+
>E.A : Symbol(E.A, Decl(a.ts, 0, 15))
14+
>E : Symbol(E, Decl(b.js, 0, 8))
15+
>A : Symbol(E.A, Decl(a.ts, 0, 15))
16+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
=== /a.ts ===
2+
export enum E { A }
3+
>E : E
4+
>A : E
5+
6+
=== /b.js ===
7+
import { E } from "./a";
8+
>E : typeof E
9+
10+
/** @type {E} */
11+
const e = E.A;
12+
>e : E
13+
>E.A : E
14+
>E : typeof E
15+
>A : E
16+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// @allowJs: true
2+
// @checkJs: true
3+
// @noEmit: true
4+
5+
// @Filename: /a.ts
6+
export enum E { A }
7+
8+
// @Filename: /b.js
9+
import { E } from "./a";
10+
/** @type {E} */
11+
const e = E.A;

0 commit comments

Comments
 (0)