diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cf2099badde..523cd139248 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -92,7 +92,8 @@ module ts { getContextualType: getContextualType, getFullyQualifiedName: getFullyQualifiedName, getResolvedSignature: getResolvedSignature, - getEnumMemberValue: getEnumMemberValue + getEnumMemberValue: getEnumMemberValue, + getUnionTypesOfUnionProperty: getUnionTypesOfUnionProperty }; var undefinedSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "undefined"); @@ -1750,6 +1751,10 @@ module ts { return links.type; } + function getUnionTypesOfUnionProperty(symbol: Symbol): Type[] { + return (symbol.flags & SymbolFlags.UnionProperty) ? getSymbolLinks(symbol).unionType.types : undefined; + } + function getTypeOfSymbol(symbol: Symbol): Type { if (symbol.flags & (SymbolFlags.Variable | SymbolFlags.Property)) { return getTypeOfVariableOrParameterOrProperty(symbol); @@ -3583,7 +3588,8 @@ module ts { } function getBestCommonType(types: Type[], contextualType?: Type): Type { - return contextualType && isSupertypeOfEach(contextualType, types) ? contextualType : getUnionType(types); } + return contextualType && isSupertypeOfEach(contextualType, types) ? contextualType : getUnionType(types); + } function isTypeOfObjectLiteral(type: Type): boolean { return (type.flags & TypeFlags.Anonymous) && type.symbol && (type.symbol.flags & SymbolFlags.ObjectLiteral) ? true : false; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f6691353c22..0d943915e44 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -657,6 +657,8 @@ module ts { getContextualType(node: Node): Type; getResolvedSignature(node: CallExpression, candidatesOutArray?: Signature[]): Signature; + getUnionTypesOfUnionProperty(symbol: Symbol): Type[]; + // Returns the constant value of this enum member, or 'undefined' if the enum member has a // computed value. getEnumMemberValue(node: EnumMember): number; diff --git a/src/services/services.ts b/src/services/services.ts index 3e222450aa7..53e6f0e1401 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2284,8 +2284,16 @@ module ts { } } + function getConcreteSymbol(symbol: Symbol): Symbol { + if (symbol.flags & SymbolFlags.UnionProperty) { + var types = typeInfoResolver.getUnionTypesOfUnionProperty(symbol); + symbol = typeInfoResolver.getPropertyOfType(types[0], symbol.name); + } + return typeInfoResolver.getRootSymbol(symbol); + } + function getSymbolKind(symbol: Symbol): string { - var flags = typeInfoResolver.getRootSymbol(symbol).getFlags(); + var flags = getConcreteSymbol(symbol).getFlags(); if (flags & SymbolFlags.Module) return ScriptElementKind.moduleElement; if (flags & SymbolFlags.Class) return ScriptElementKind.classElement; @@ -2344,6 +2352,7 @@ module ts { } function getSymbolModifiers(symbol: Symbol): string { + symbol = getConcreteSymbol(symbol); return symbol && symbol.declarations && symbol.declarations.length > 0 ? getNodeModifiers(symbol.declarations[0]) : ScriptElementKindModifier.none; diff --git a/tests/cases/fourslash/completionEntryForUnionProperty.ts b/tests/cases/fourslash/completionEntryForUnionProperty.ts new file mode 100644 index 00000000000..6d5a3627a9c --- /dev/null +++ b/tests/cases/fourslash/completionEntryForUnionProperty.ts @@ -0,0 +1,20 @@ +/// + +////interface One { +//// commonProperty: number; +//// commonFunction(): number; +////} +//// +////interface Two { +//// commonProperty: string +//// commonFunction(): number; +////} +//// +////var x : One | Two; +//// +////x./**/ + +goTo.marker(); +verify.memberListContains("commonProperty", "string | number", undefined, undefined, "property"); +verify.memberListContains("commonFunction", "() => number", undefined, undefined, "method"); +verify.memberListCount(2); \ No newline at end of file