Repository navigation
Autocomplete breaks after one property for an array generic #57879
Description
🔎 Search Terms
array generic
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about generics
⏯ Playground Link
💻 Code
type ModelClause<T> = {
OR?: ModelClause<T>[];
AND?: ModelClause<T>[];
} & Partial<T>;
type BaseQuery<T extends string, U extends object> = {
model: T;
query?: ModelClause<U>;
};
type UserQuery = BaseQuery<"User", { name: string; age: number }>;
type PostsQuery = BaseQuery<"Posts", { title: string; content: string }>;
type Query = UserQuery | PostsQuery;
function testing<T extends Query>(query: T[]) {
console.log(query);
}
function testing2<T extends Query[]>(query: T) {
console.log(query);
}
testing([
{
model: "User",
query: {
name: "test",
// Typing age here will autocomplete
age: 10
},
},
]);
testing2([
{
model: "User",
query: {
name: "test",
// Try typing age here, it won't autocomplete
},
},
]);🙁 Actual behavior
For the testing function, you correctly get suggested fields when filling in the query property.
However, for testing2, the suggestion works for your first property, whichever one you try.
However, once the first one is provided, it will stop autocompleting.
Once one has been provided, you can also list any key, regardless of if it's part of the model.
🙂 Expected behavior
It should correctly suggest all properties and typecheck additional properties and not stop working after the first one.
Additional information about the issue
Some extra context why I'm using the testing2 approach, here's a playground link that shows what I'm trying to achieve.
Basically, I want to make sure that the return value of my function adheres to what was passed in. I haven't found a way to do it with testing, so I went for testing2, which is a decrease in DX since it'll only autocomplete one query parameter.
But the return value is exactly what I want
(for reference for others who would stumble upon this issue, the last as const is important to ensure it returns the correct order, else it will have a type of const returnValue: (UserModel | PostModel)[])








Activity
Andarist commentedon Mar 21, 2024
If you don't need to infer
queriesthen this works reasonably well: TS playgroundRareSecond commentedon Mar 21, 2024
Amazing, this works super smooth! Notice for further readers: the correct typing of the tuple will only work on TypeScript >5.4.
If you would have some spare time, could you explain the differences and why your approach is better?
Andarist commentedon Mar 21, 2024
With a small adjustment you can also make it work with TS 5.3: TS playground
I think it's better because it gives you a clear way of relating "positional inferences". The
querytype depends on its own siblingmodel- you don't even have to create a discriminated union to achieve this. So it's more flexible because you can introduce such dependencies withunknownconstraints.I don't know why the autocompletes work in this particular way on your two first examples. This might be worth investigating or something. I know though that often autocompletes in objects for optional properties etc might stop working in inference contexts. The problem is that the inferred type (like even
{}) is already valid at a particular position and TS sees that type there and not the original constraint based on which it was inferred. So there is no source from which those properties could be obtained. There are some internal ways to query those types with different flags so the constraint can actually often be obtained in such positions but not every call site is querying completions from both types (with inference enabled and with inference blocked on the source location).RyanCavanaugh commentedon Dec 3, 2025
Closing language service bugs related to the 6.0 implementation. For more information, see #62827