mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 03:23:08 -06:00
Filter out self-fulfilling completions (#35709)
This commit is contained in:
parent
ec84392f2e
commit
1fd5bd2b4e
@ -2540,11 +2540,12 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
function getPropertiesForObjectExpression(contextualType: Type, baseConstrainedType: Type | undefined, obj: ObjectLiteralExpression | JsxAttributes, checker: TypeChecker): Symbol[] {
|
||||
const type = baseConstrainedType && !(baseConstrainedType.flags & TypeFlags.AnyOrUnknown)
|
||||
? checker.getUnionType([contextualType, baseConstrainedType])
|
||||
const hasBaseType = baseConstrainedType && baseConstrainedType !== contextualType;
|
||||
const type = hasBaseType && !(baseConstrainedType!.flags & TypeFlags.AnyOrUnknown)
|
||||
? checker.getUnionType([contextualType, baseConstrainedType!])
|
||||
: contextualType;
|
||||
|
||||
return type.isUnion()
|
||||
const properties = type.isUnion()
|
||||
? checker.getAllPossiblePropertiesOfTypes(type.types.filter(memberType =>
|
||||
// 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.
|
||||
!(memberType.flags & TypeFlags.Primitive ||
|
||||
@ -2552,6 +2553,17 @@ namespace ts.Completions {
|
||||
typeHasCallOrConstructSignatures(memberType, checker) ||
|
||||
checker.isTypeInvalidDueToUnionDiscriminant(memberType, obj))))
|
||||
: type.getApparentProperties();
|
||||
|
||||
return hasBaseType ? properties.filter(hasDeclarationOtherThanSelf) : properties;
|
||||
|
||||
// Filter out members whose only declaration is the object literal itself to avoid
|
||||
// self-fulfilling completions like:
|
||||
//
|
||||
// function f<T>(x: T) {}
|
||||
// f({ abc/**/: "" }) // `abc` is a member of `T` but only because it declares itself
|
||||
function hasDeclarationOtherThanSelf(member: Symbol) {
|
||||
return some(member.declarations, decl => decl.parent !== obj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
23
tests/cases/fourslash/completionsSelfDeclaring1.ts
Normal file
23
tests/cases/fourslash/completionsSelfDeclaring1.ts
Normal file
@ -0,0 +1,23 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////interface Test {
|
||||
//// keyPath?: string;
|
||||
//// autoIncrement?: boolean;
|
||||
////}
|
||||
////
|
||||
////function test<T extends Record<string, Test>>(opt: T) { }
|
||||
////
|
||||
////test({
|
||||
//// a: {
|
||||
//// keyPath: '',
|
||||
//// a/**/
|
||||
//// }
|
||||
////})
|
||||
|
||||
verify.completions({
|
||||
marker: "",
|
||||
exact: [{
|
||||
name: "autoIncrement",
|
||||
sortText: completion.SortText.OptionalMember
|
||||
}]
|
||||
});
|
||||
18
tests/cases/fourslash/completionsSelfDeclaring2.ts
Normal file
18
tests/cases/fourslash/completionsSelfDeclaring2.ts
Normal file
@ -0,0 +1,18 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////function f1<T>(x: T) {}
|
||||
////f1({ abc/*1*/ });
|
||||
////
|
||||
////function f2<T extends { xyz: number }>(x: T) {}
|
||||
////f2({ x/*2*/ });
|
||||
|
||||
|
||||
verify.completions({
|
||||
marker: "1",
|
||||
exact: []
|
||||
});
|
||||
|
||||
verify.completions({
|
||||
marker: "2",
|
||||
exact: ["xyz"]
|
||||
});
|
||||
25
tests/cases/fourslash/completionsSelfDeclaring3.ts
Normal file
25
tests/cases/fourslash/completionsSelfDeclaring3.ts
Normal file
@ -0,0 +1,25 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////function f<T extends { x: number }>(p: T & (T extends { hello: string } ? { goodbye: number } : {})) {}
|
||||
////f({ x/*x*/: 0, hello/*hello*/: "", goodbye/*goodbye*/: 0, abc/*abc*/: "" })
|
||||
|
||||
|
||||
verify.completions({
|
||||
marker: "x",
|
||||
exact: ["x"]
|
||||
});
|
||||
|
||||
verify.completions({
|
||||
marker: "hello",
|
||||
exact: []
|
||||
});
|
||||
|
||||
verify.completions({
|
||||
marker: "goodbye",
|
||||
exact: ["goodbye"]
|
||||
});
|
||||
|
||||
verify.completions({
|
||||
marker: "abc",
|
||||
exact: []
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user