@@ -1279,7 +1279,7 @@ namespace ts.Completions {
1279
1279
// Cursor is inside a JSX self-closing element or opening element
1280
1280
const attrsType = jsxContainer && typeChecker . getContextualType ( jsxContainer . attributes ) ;
1281
1281
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 ) ;
1283
1283
setSortTextToOptionalMember ( ) ;
1284
1284
completionKind = CompletionKind . MemberLike ;
1285
1285
isNewIdentifierLocation = false ;
@@ -1795,10 +1795,11 @@ namespace ts.Completions {
1795
1795
let existingMembers : readonly Declaration [ ] | undefined ;
1796
1796
1797
1797
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 ) ;
1802
1803
existingMembers = objectLikeContainer . properties ;
1803
1804
}
1804
1805
else {
@@ -2535,15 +2536,19 @@ namespace ts.Completions {
2535
2536
return jsdoc && jsdoc . tags && ( rangeContainsPosition ( jsdoc , position ) ? findLast ( jsdoc . tags , tag => tag . pos < position ) : undefined ) ;
2536
2537
}
2537
2538
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 =>
2541
2546
// 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.
2542
2547
! ( memberType . flags & TypeFlags . Primitive ||
2543
2548
checker . isArrayLikeType ( memberType ) ||
2544
2549
typeHasCallOrConstructSignatures ( memberType , checker ) ||
2545
2550
checker . isTypeInvalidDueToUnionDiscriminant ( memberType , obj ) ) ) )
2546
- : contextualType . getApparentProperties ( ) ;
2551
+ : type . getApparentProperties ( ) ;
2547
2552
}
2548
2553
2549
2554
/**
0 commit comments