microsoft/TypeScript

Autocomplete of bracket property doesn't work with `useState`

Opened this issue · 7 comments

vbeffa commented

Type: Bug

There are probably other instances where it doesn't work. Note in the first screenshot, the closing quote and bracket are present, but not the closing >. I have to navigate and insert that before I get an actual list of properties (second screenshot). However, in the third screenshot, I have a property where I haven't even closed the quote and bracket, and I still get the correct list of properties in the popup. I would expect this to always show whenever [' is present after a type.

VS Code version: Code 1.105.1 (Universal) (7d842fb85a0275a4a8e4d7e040d2625abbf7f084, 2025-10-14T22:33:36.618Z)
OS version: Darwin x64 21.6.0
Modes:

Image Image Image

This issue lacks

  • copy-paste friendly, minimal code sample
  • name of the language/extension this happens with
vbeffa commented

Typescript/React. Code below; also attaching video.

import { useState } from 'react';

type Foo = {
  bar: number;
  baz: string;
}

type Bar = {
  foo: Foo[''] // after typing [ and ' the closing ] and ' are auto-completed, and the popup automatically appears and shows `bar` and `baz`
}

const Component = () => {
  const [bip, setBip] = useState<Foo[''] // after typing [ and ' the closing ] and ' are auto-completed but there is no popup; ctrl-space brings up meaningless context; only after adding the closing `>` and putting the cursor back between the quotes and hitting ctrl-space does the popup show `bar` and `baz`
}

export default Component;
Screen.Recording.2025-11-04.at.11.00.07.AM.mov
const Component = () => {
  const [bip, setBip] = useState<Foo['']
}

unfortunately at this syntactic state, it looks like you're writing

useState < Foo['']
         ^ less-than operator

so the nonexistent value Foo doesn't have anything to access via []

There's not much we can do here; it's literally possible that you were legally doing the other thing instead

Image
vbeffa commented

But useState is not a value in the current context, so comparing it to another nonexistent value doesn't make sense. It is, however, an imported method, which has type parameters. And in fact the IDE does recognize this; see recording. Notice that as soon as I type the opening < (and not before), the popup appears showing the method documentation with its type parameter.

Screen.Recording.2025-11-05.at.3.47.03.PM.mov

But useState is not a value in the current context

Not sure what you're getting at here. It's a value, otherwise you wouldn't be able to call it.

vbeffa commented

I meant that it's a method and not a primitive type. In any case, as I pointed out, the IDE correctly detects that the < is the start of a type parameter, as evidenced by the method popup that is shown. So it should be possible to determine the autocomplete to show when you type ['. And in fact, based on your example, the IDE is deciding to show qua in the situation where you're comparing useState rather than treating it as a type parameter. The former is an edge case; I don't see why the IDE would decide to parse it that way (while also showing the correct method popup, which is contradictory).

But useState is not a value in the current context, so comparing it to another nonexistent value doesn't make sense.

I meant that it's a method and not a primitive type.

Unfortunately, comparing functions is legal in JavaScript/TypeScript.