Fix declaration emit for cross-file enums (#28237)

This commit is contained in:
Wesley Wigham
2018-10-30 14:55:01 -07:00
committed by GitHub
parent 0481d44501
commit 4cfff8962c
6 changed files with 188 additions and 8 deletions

View File

@@ -3222,15 +3222,17 @@ namespace ts {
}
if (type.flags & TypeFlags.EnumLiteral && !(type.flags & TypeFlags.Union)) {
const parentSymbol = getParentOfSymbol(type.symbol)!;
const parentName = symbolToName(parentSymbol, context, SymbolFlags.Type, /*expectsIdentifier*/ false);
const enumLiteralName = getDeclaredTypeOfSymbol(parentSymbol) === type ? parentName : createQualifiedName(parentName, symbolName(type.symbol));
context.approximateLength += symbolName(type.symbol).length;
return createTypeReferenceNode(enumLiteralName, /*typeArguments*/ undefined);
const parentName = symbolToTypeNode(parentSymbol, context, SymbolFlags.Type);
const enumLiteralName = getDeclaredTypeOfSymbol(parentSymbol) === type
? parentName
: appendReferenceToType(
parentName as TypeReferenceNode | ImportTypeNode,
createTypeReferenceNode(symbolName(type.symbol), /*typeArguments*/ undefined)
);
return enumLiteralName;
}
if (type.flags & TypeFlags.EnumLike) {
const name = symbolToName(type.symbol, context, SymbolFlags.Type, /*expectsIdentifier*/ false);
context.approximateLength += symbolName(type.symbol).length;
return createTypeReferenceNode(name, /*typeArguments*/ undefined);
return symbolToTypeNode(type.symbol, context, SymbolFlags.Type);
}
if (type.flags & TypeFlags.StringLiteral) {
context.approximateLength += ((<StringLiteralType>type).value.length + 2);

View File

@@ -0,0 +1,40 @@
//// [tests/cases/compiler/declarationEmitQualifiedAliasTypeArgument.ts] ////
//// [bbb.d.ts]
export interface INode<T> {
data: T;
}
export function create<T>(): () => INode<T>;
//// [lib.d.ts]
export type G<T extends string> = { [P in T]: string };
export enum E {
A = "a",
B = "b"
}
export type T = G<E>;
export type Q = G<E.A>;
//// [index.ts]
import { T, Q } from "./lib";
import { create } from "./bbb";
export const fun = create<T>();
export const fun2 = create<Q>();
//// [index.js]
"use strict";
exports.__esModule = true;
var bbb_1 = require("./bbb");
exports.fun = bbb_1.create();
exports.fun2 = bbb_1.create();
//// [index.d.ts]
export declare const fun: () => import("./bbb").INode<import("./lib").G<import("./lib").E>>;
export declare const fun2: () => import("./bbb").INode<import("./lib").G<import("./lib").E.A>>;

View File

@@ -0,0 +1,62 @@
=== tests/cases/compiler/bbb.d.ts ===
export interface INode<T> {
>INode : Symbol(INode, Decl(bbb.d.ts, 0, 0))
>T : Symbol(T, Decl(bbb.d.ts, 0, 23))
data: T;
>data : Symbol(INode.data, Decl(bbb.d.ts, 0, 27))
>T : Symbol(T, Decl(bbb.d.ts, 0, 23))
}
export function create<T>(): () => INode<T>;
>create : Symbol(create, Decl(bbb.d.ts, 2, 1))
>T : Symbol(T, Decl(bbb.d.ts, 4, 23))
>INode : Symbol(INode, Decl(bbb.d.ts, 0, 0))
>T : Symbol(T, Decl(bbb.d.ts, 4, 23))
=== tests/cases/compiler/lib.d.ts ===
export type G<T extends string> = { [P in T]: string };
>G : Symbol(G, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(lib.d.ts, --, --))
>P : Symbol(P, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(lib.d.ts, --, --))
export enum E {
>E : Symbol(E, Decl(lib.d.ts, --, --))
A = "a",
>A : Symbol(E.A, Decl(lib.d.ts, --, --))
B = "b"
>B : Symbol(E.B, Decl(lib.d.ts, --, --))
}
export type T = G<E>;
>T : Symbol(T, Decl(lib.d.ts, --, --))
>G : Symbol(G, Decl(lib.d.ts, --, --))
>E : Symbol(E, Decl(lib.d.ts, --, --))
export type Q = G<E.A>;
>Q : Symbol(Q, Decl(lib.d.ts, --, --))
>G : Symbol(G, Decl(lib.d.ts, --, --))
>E : Symbol(E, Decl(lib.d.ts, --, --))
>A : Symbol(E.A, Decl(lib.d.ts, --, --))
=== tests/cases/compiler/index.ts ===
import { T, Q } from "./lib";
>T : Symbol(T, Decl(index.ts, 0, 8))
>Q : Symbol(Q, Decl(index.ts, 0, 11))
import { create } from "./bbb";
>create : Symbol(create, Decl(index.ts, 1, 8))
export const fun = create<T>();
>fun : Symbol(fun, Decl(index.ts, 3, 12))
>create : Symbol(create, Decl(index.ts, 1, 8))
>T : Symbol(T, Decl(index.ts, 0, 8))
export const fun2 = create<Q>();
>fun2 : Symbol(fun2, Decl(index.ts, 5, 12))
>create : Symbol(create, Decl(index.ts, 1, 8))
>Q : Symbol(Q, Decl(index.ts, 0, 11))

View File

@@ -0,0 +1,50 @@
=== tests/cases/compiler/bbb.d.ts ===
export interface INode<T> {
data: T;
>data : T
}
export function create<T>(): () => INode<T>;
>create : <T>() => () => INode<T>
=== tests/cases/compiler/lib.d.ts ===
export type G<T extends string> = { [P in T]: string };
>G : G<T>
export enum E {
>E : E
A = "a",
>A : E.A
>"a" : "a"
B = "b"
>B : E.B
>"b" : "b"
}
export type T = G<E>;
>T : G<E>
export type Q = G<E.A>;
>Q : G<E.A>
>E : any
=== tests/cases/compiler/index.ts ===
import { T, Q } from "./lib";
>T : any
>Q : any
import { create } from "./bbb";
>create : <T>() => () => import("tests/cases/compiler/bbb").INode<T>
export const fun = create<T>();
>fun : () => import("tests/cases/compiler/bbb").INode<import("tests/cases/compiler/lib").G<import("tests/cases/compiler/lib").E>>
>create<T>() : () => import("tests/cases/compiler/bbb").INode<import("tests/cases/compiler/lib").G<import("tests/cases/compiler/lib").E>>
>create : <T>() => () => import("tests/cases/compiler/bbb").INode<T>
export const fun2 = create<Q>();
>fun2 : () => import("tests/cases/compiler/bbb").INode<import("tests/cases/compiler/lib").G<import("tests/cases/compiler/lib").E.A>>
>create<Q>() : () => import("tests/cases/compiler/bbb").INode<import("tests/cases/compiler/lib").G<import("tests/cases/compiler/lib").E.A>>
>create : <T>() => () => import("tests/cases/compiler/bbb").INode<T>

View File

@@ -0,0 +1,26 @@
// @declaration: true
// @filename: bbb.d.ts
export interface INode<T> {
data: T;
}
export function create<T>(): () => INode<T>;
// @filename: lib.d.ts
export type G<T extends string> = { [P in T]: string };
export enum E {
A = "a",
B = "b"
}
export type T = G<E>;
export type Q = G<E.A>;
// @filename: index.ts
import { T, Q } from "./lib";
import { create } from "./bbb";
export const fun = create<T>();
export const fun2 = create<Q>();