@@ -1279,7 +1279,7 @@ namespace ts.Completions {
12791279 // Cursor is inside a JSX self-closing element or opening element
12801280 const attrsType = jsxContainer && typeChecker . getContextualType ( jsxContainer . attributes ) ;
12811281 if ( ! attrsType ) return GlobalsSearch . Continue ;
1282- symbols = filterJsxAttributes ( getPropertiesForObjectExpression ( attrsType , jsxContainer ! . attributes , typeChecker ) , jsxContainer ! . attributes . properties ) ;
1282+ symbols = filterJsxAttributes ( getPropertiesForObjectExpression ( attrsType , /*baseType*/ undefined , jsxContainer ! . attributes , typeChecker ) , jsxContainer ! . attributes . properties ) ;
12831283 setSortTextToOptionalMember ( ) ;
12841284 completionKind = CompletionKind . MemberLike ;
12851285 isNewIdentifierLocation = false ;
@@ -1795,10 +1795,11 @@ namespace ts.Completions {
17951795 let existingMembers : readonly Declaration [ ] | undefined ;
17961796
17971797 if ( objectLikeContainer . kind === SyntaxKind . ObjectLiteralExpression ) {
1798- const typeForObject = typeChecker . getContextualType ( objectLikeContainer , ContextFlags . Completion ) ;
1799- if ( ! typeForObject ) return GlobalsSearch . Fail ;
1800- isNewIdentifierLocation = hasIndexSignature ( typeForObject ) ;
1801- typeMembers = getPropertiesForObjectExpression ( typeForObject , objectLikeContainer , typeChecker ) ;
1798+ const instantiatedType = typeChecker . getContextualType ( objectLikeContainer ) ;
1799+ const baseType = instantiatedType && typeChecker . getContextualType ( objectLikeContainer , ContextFlags . BaseConstraint ) ;
1800+ if ( ! instantiatedType || ! baseType ) return GlobalsSearch . Fail ;
1801+ isNewIdentifierLocation = hasIndexSignature ( instantiatedType || baseType ) ;
1802+ typeMembers = getPropertiesForObjectExpression ( instantiatedType , baseType , objectLikeContainer , typeChecker ) ;
18021803 existingMembers = objectLikeContainer . properties ;
18031804 }
18041805 else {
@@ -2535,15 +2536,19 @@ namespace ts.Completions {
25352536 return jsdoc && jsdoc . tags && ( rangeContainsPosition ( jsdoc , position ) ? findLast ( jsdoc . tags , tag => tag . pos < position ) : undefined ) ;
25362537 }
25372538
2538- function getPropertiesForObjectExpression ( contextualType : Type , obj : ObjectLiteralExpression | JsxAttributes , checker : TypeChecker ) : Symbol [ ] {
2539- return contextualType . isUnion ( )
2540- ? checker . getAllPossiblePropertiesOfTypes ( contextualType . types . filter ( memberType =>
2539+ function getPropertiesForObjectExpression ( contextualType : Type , baseConstrainedType : Type | undefined , obj : ObjectLiteralExpression | JsxAttributes , checker : TypeChecker ) : Symbol [ ] {
2540+ const type = baseConstrainedType && ! ( baseConstrainedType . flags & TypeFlags . AnyOrUnknown )
2541+ ? checker . getUnionType ( [ contextualType , baseConstrainedType ] )
2542+ : contextualType ;
2543+
2544+ return type . isUnion ( )
2545+ ? checker . getAllPossiblePropertiesOfTypes ( type . types . filter ( memberType =>
25412546 // If we're providing completions for an object literal, skip primitive, array-like, or callable types since those shouldn't be implemented by object literals.
25422547 ! ( memberType . flags & TypeFlags . Primitive ||
25432548 checker . isArrayLikeType ( memberType ) ||
25442549 typeHasCallOrConstructSignatures ( memberType , checker ) ||
25452550 checker . isTypeInvalidDueToUnionDiscriminant ( memberType , obj ) ) ) )
2546- : contextualType . getApparentProperties ( ) ;
2551+ : type . getApparentProperties ( ) ;
25472552 }
25482553
25492554 /**
0 commit comments