@@ -2609,7 +2609,11 @@ namespace ts {
2609
2609
if (!inTypeAlias && type.aliasSymbol && isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration)) {
2610
2610
const name = symbolToTypeReferenceName(type.aliasSymbol);
2611
2611
const typeArgumentNodes = mapToTypeNodes(type.aliasTypeArguments, context);
2612
- return createTypeReferenceNode(name, typeArgumentNodes);
2612
+ const ref = createTypeReferenceNode(name, typeArgumentNodes);
2613
+ if (type.aliasKind === AliasKind.KeyOf) {
2614
+ return createTypeOperatorNode(ref);
2615
+ }
2616
+ return ref;
2613
2617
}
2614
2618
if (type.flags & (TypeFlags.Union | TypeFlags.Intersection)) {
2615
2619
const types = type.flags & TypeFlags.Union ? formatUnionTypes((<UnionType>type).types) : (<IntersectionType>type).types;
@@ -3369,6 +3373,10 @@ namespace ts {
3369
3373
}
3370
3374
else if (!(flags & TypeFormatFlags.InTypeAlias) && type.aliasSymbol &&
3371
3375
((flags & TypeFormatFlags.UseAliasDefinedOutsideCurrentScope) || isTypeSymbolAccessible(type.aliasSymbol, enclosingDeclaration))) {
3376
+ if (type.aliasKind === AliasKind.KeyOf) {
3377
+ writer.writeKeyword("keyof");
3378
+ writeSpace(writer);
3379
+ }
3372
3380
const typeArguments = type.aliasTypeArguments;
3373
3381
writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, length(typeArguments), nextFlags);
3374
3382
}
@@ -7879,7 +7887,7 @@ namespace ts {
7879
7887
// expression constructs such as array literals and the || and ?: operators). Named types can
7880
7888
// circularly reference themselves and therefore cannot be subtype reduced during their declaration.
7881
7889
// For example, "type Item = string | (() => Item" is a named type that circularly references itself.
7882
- function getUnionType(types: Type[], unionReduction: UnionReduction = UnionReduction.Literal, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
7890
+ function getUnionType(types: Type[], unionReduction: UnionReduction = UnionReduction.Literal, aliasSymbol?: Symbol, aliasTypeArguments?: Type[], aliasKind?: AliasKind ): Type {
7883
7891
if (types.length === 0) {
7884
7892
return neverType;
7885
7893
}
@@ -7906,7 +7914,7 @@ namespace ts {
7906
7914
typeSet.containsUndefined ? typeSet.containsNonWideningType ? undefinedType : undefinedWideningType :
7907
7915
neverType;
7908
7916
}
7909
- return getUnionTypeFromSortedList(typeSet, aliasSymbol, aliasTypeArguments);
7917
+ return getUnionTypeFromSortedList(typeSet, aliasSymbol, aliasTypeArguments, aliasKind );
7910
7918
}
7911
7919
7912
7920
function getUnionTypePredicate(signatures: ReadonlyArray<Signature>): TypePredicate {
@@ -7946,7 +7954,7 @@ namespace ts {
7946
7954
}
7947
7955
7948
7956
// This function assumes the constituent type list is sorted and deduplicated.
7949
- function getUnionTypeFromSortedList(types: Type[], aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
7957
+ function getUnionTypeFromSortedList(types: Type[], aliasSymbol?: Symbol, aliasTypeArguments?: Type[], aliasKind?: AliasKind ): Type {
7950
7958
if (types.length === 0) {
7951
7959
return neverType;
7952
7960
}
@@ -7968,6 +7976,7 @@ namespace ts {
7968
7976
*/
7969
7977
type.aliasSymbol = aliasSymbol;
7970
7978
type.aliasTypeArguments = aliasTypeArguments;
7979
+ type.aliasKind = aliasKind;
7971
7980
}
7972
7981
return type;
7973
7982
}
@@ -8089,7 +8098,19 @@ namespace ts {
8089
8098
}
8090
8099
8091
8100
function getLiteralTypeFromPropertyNames(type: Type) {
8092
- return getUnionType(map(getPropertiesOfType(type), getLiteralTypeFromPropertyName));
8101
+ let aliasSymbol: Symbol;
8102
+ let aliasTypeArguments: Type[];
8103
+ if (type.aliasSymbol && !type.aliasKind) {
8104
+ aliasSymbol = type.aliasSymbol;
8105
+ aliasTypeArguments = type.aliasTypeArguments;
8106
+ }
8107
+ else if (type.aliasSymbol && type.aliasKind === AliasKind.KeyOf) {
8108
+ aliasSymbol = getGlobalSymbol("String" as __String, SymbolFlags.Type, /*diagnostic*/ undefined);
8109
+ }
8110
+ else if (type.symbol && type.symbol.flags & SymbolFlags.Interface) {
8111
+ aliasSymbol = type.symbol;
8112
+ }
8113
+ return getUnionType(map(getPropertiesOfType(type), getLiteralTypeFromPropertyName), UnionReduction.Literal, aliasSymbol, aliasTypeArguments, AliasKind.KeyOf);
8093
8114
}
8094
8115
8095
8116
function getIndexType(type: Type): Type {
0 commit comments