Support accessing enum types from JSDoc (#18703)

This commit is contained in:
Andy 2017-09-28 13:43:39 -07:00 committed by GitHub
parent 0b7dd5a4a5
commit 4bba6ee02e
4 changed files with 73 additions and 27 deletions

View File

@ -5252,6 +5252,10 @@ namespace ts {
}
function getDeclaredTypeOfSymbol(symbol: Symbol): Type {
return tryGetDeclaredTypeOfSymbol(symbol) || unknownType;
}
function tryGetDeclaredTypeOfSymbol(symbol: Symbol): Type | undefined {
if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
return getDeclaredTypeOfClassOrInterface(symbol);
}
@ -5270,7 +5274,7 @@ namespace ts {
if (symbol.flags & SymbolFlags.Alias) {
return getDeclaredTypeOfAlias(symbol);
}
return unknownType;
return undefined;
}
// A type reference is considered independent if each type argument is considered independent.
@ -6872,17 +6876,6 @@ namespace ts {
return type;
}
/**
* Get type from reference to named type that cannot be generic (enum or type parameter)
*/
function getTypeFromNonGenericTypeReference(node: TypeReferenceType, symbol: Symbol): Type {
if (node.typeArguments) {
error(node, Diagnostics.Type_0_is_not_generic, symbolToString(symbol));
return unknownType;
}
return getDeclaredTypeOfSymbol(symbol);
}
function getTypeReferenceName(node: TypeReferenceType): EntityNameOrEntityNameExpression | undefined {
switch (node.kind) {
case SyntaxKind.TypeReference:
@ -6919,24 +6912,34 @@ namespace ts {
return type;
}
if (symbol.flags & SymbolFlags.Value && isJSDocTypeReference(node)) {
// A jsdoc TypeReference may have resolved to a value (as opposed to a type). If
// the symbol is a constructor function, return the inferred class type; otherwise,
// the type of this reference is just the type of the value we resolved to.
const valueType = getTypeOfSymbol(symbol);
if (valueType.symbol && !isInferredClassType(valueType)) {
const referenceType = getTypeReferenceTypeWorker(node, valueType.symbol, typeArguments);
if (referenceType) {
return referenceType;
}
// Get type from reference to named type that cannot be generic (enum or type parameter)
const res = tryGetDeclaredTypeOfSymbol(symbol);
if (res !== undefined) {
if (typeArguments) {
error(node, Diagnostics.Type_0_is_not_generic, symbolToString(symbol));
return unknownType;
}
// Resolve the type reference as a Type for the purpose of reporting errors.
resolveTypeReferenceName(getTypeReferenceName(node), SymbolFlags.Type);
return valueType;
return res;
}
return getTypeFromNonGenericTypeReference(node, symbol);
if (!(symbol.flags & SymbolFlags.Value && isJSDocTypeReference(node))) {
return unknownType;
}
// A jsdoc TypeReference may have resolved to a value (as opposed to a type). If
// the symbol is a constructor function, return the inferred class type; otherwise,
// the type of this reference is just the type of the value we resolved to.
const valueType = getTypeOfSymbol(symbol);
if (valueType.symbol && !isInferredClassType(valueType)) {
const referenceType = getTypeReferenceTypeWorker(node, valueType.symbol, typeArguments);
if (referenceType) {
return referenceType;
}
}
// Resolve the type reference as a Type for the purpose of reporting errors.
resolveTypeReferenceName(getTypeReferenceName(node), SymbolFlags.Type);
return valueType;
}
function getTypeReferenceTypeWorker(node: TypeReferenceType, symbol: Symbol, typeArguments: Type[]): Type | undefined {

View File

@ -0,0 +1,16 @@
=== /a.ts ===
export enum E { A }
>E : Symbol(E, Decl(a.ts, 0, 0))
>A : Symbol(E.A, Decl(a.ts, 0, 15))
=== /b.js ===
import { E } from "./a";
>E : Symbol(E, Decl(b.js, 0, 8))
/** @type {E} */
const e = E.A;
>e : Symbol(e, Decl(b.js, 2, 5))
>E.A : Symbol(E.A, Decl(a.ts, 0, 15))
>E : Symbol(E, Decl(b.js, 0, 8))
>A : Symbol(E.A, Decl(a.ts, 0, 15))

View File

@ -0,0 +1,16 @@
=== /a.ts ===
export enum E { A }
>E : E
>A : E
=== /b.js ===
import { E } from "./a";
>E : typeof E
/** @type {E} */
const e = E.A;
>e : E
>E.A : E
>E : typeof E
>A : E

View File

@ -0,0 +1,11 @@
// @allowJs: true
// @checkJs: true
// @noEmit: true
// @Filename: /a.ts
export enum E { A }
// @Filename: /b.js
import { E } from "./a";
/** @type {E} */
const e = E.A;