@@ -3306,6 +3306,15 @@ namespace ts {
33063306 return getSignaturesOfObjectOrUnionType(getApparentType(type), kind);
33073307 }
33083308
3309+ function typeHasConstructSignatures(type: Type): boolean {
3310+ let apparentType = getApparentType(type);
3311+ if (apparentType.flags & (TypeFlags.ObjectType | TypeFlags.Union)) {
3312+ let resolved = resolveObjectOrUnionTypeMembers(<ObjectType>type);
3313+ return resolved.constructSignatures.length > 0;
3314+ }
3315+ return false;
3316+ }
3317+
33093318 function typeHasCallOrConstructSignatures(type: Type): boolean {
33103319 let apparentType = getApparentType(type);
33113320 if (apparentType.flags & (TypeFlags.ObjectType | TypeFlags.Union)) {
@@ -13207,15 +13216,53 @@ namespace ts {
1320713216
1320813217 return undefined;
1320913218 }
13219+
13220+ function isFunctionType(type: Type): boolean {
13221+ return type.flags & TypeFlags.ObjectType && getSignaturesOfType(type, SignatureKind.Call).length > 0;
13222+ }
1321013223
13211- function isTypeReferenceWithValueDeclaration(node: TypeReferenceNode): boolean {
13224+ function isTypeWithValue(node: TypeReferenceNode): TypeWithValueResolutionResult {
13225+ // Resolve the symbol as a value to ensure the type can be reached at runtime during emit.
1321213226 let symbol = resolveEntityName(node.typeName, SymbolFlags.Value, /*ignoreErrors*/ true);
13213- if (symbol.valueDeclaration) {
13214- let type = getTypeOfSymbol(symbol);
13215- return typeHasCallOrConstructSignatures(type);
13227+ let constructorType = symbol ? getTypeOfSymbol(symbol) : undefined;
13228+ if (constructorType && isConstructorType(constructorType)) {
13229+ return TypeWithValueResolutionResult.ConstructorTypeWithValue;
13230+ }
13231+
13232+ let type = getTypeFromTypeNode(node);
13233+ if (type === unknownType) {
13234+ return TypeWithValueResolutionResult.Unknown;
13235+ }
13236+ else if (type.flags & TypeFlags.Any) {
13237+ return TypeWithValueResolutionResult.ObjectType;
13238+ }
13239+ else if (allConstituentTypesHaveKind(type, TypeFlags.Void)) {
13240+ return TypeWithValueResolutionResult.VoidType;
13241+ }
13242+ else if (allConstituentTypesHaveKind(type, TypeFlags.Boolean)) {
13243+ return TypeWithValueResolutionResult.BooleanType;
13244+ }
13245+ else if (allConstituentTypesHaveKind(type, TypeFlags.NumberLike)) {
13246+ return TypeWithValueResolutionResult.NumberType;
13247+ }
13248+ else if (allConstituentTypesHaveKind(type, TypeFlags.StringLike)) {
13249+ return TypeWithValueResolutionResult.StringType;
13250+ }
13251+ else if (allConstituentTypesHaveKind(type, TypeFlags.Tuple)) {
13252+ return TypeWithValueResolutionResult.ArrayType;
13253+ }
13254+ else if (allConstituentTypesHaveKind(type, TypeFlags.ESSymbol)) {
13255+ return TypeWithValueResolutionResult.ESSymbolType;
13256+ }
13257+ else if (isFunctionType(type)) {
13258+ return TypeWithValueResolutionResult.FunctionType;
13259+ }
13260+ else if (isArrayType(type)) {
13261+ return TypeWithValueResolutionResult.ArrayType;
13262+ }
13263+ else {
13264+ return TypeWithValueResolutionResult.ObjectType;
1321613265 }
13217-
13218- return false;
1321913266 }
1322013267
1322113268 function writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter) {
@@ -13315,7 +13362,7 @@ namespace ts {
1331513362 collectLinkedAliases,
1331613363 getBlockScopedVariableId,
1331713364 getReferencedValueDeclaration,
13318- isTypeReferenceWithValueDeclaration ,
13365+ isTypeWithValue ,
1331913366 };
1332013367 }
1332113368
0 commit comments