microsoft / microsoft/TypeScript

Writes to indexed access of an index signature are not sufficiently constrained

Offen
#60,703 5 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Experimentation Needed Suggestion
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.3k
Ø Merge
1 T. 19 Std.
Gemergte PRs (30 T.)
117

Beschreibung

🔎 Search Terms

"return type" "generic" "type parameter" "indexed access" "index signature" "assignable" "constraint"

🕗 Version & Regression Information
  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about index signatures
⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.7.2#code/C4TwDgpgBAogHgQwLZgDbQLxQN4CgpQIBcUA5AqflANoDWEIJAzsAE4CWAdgOYC6zbLt1wBfXLgAmEAMaoEraNID2nFlAiIU6EvGRoIuZauBR6IAIwCOPKFnKUNe9HQbnetspyUmKUAPR+UF7qrKxKrOJSsvKKKmpmAEwk9lAAPmQARg6a+i4gCe52Xj6k-oEQoeEANIRM6nCQ0sAQEkA

💻 Code
type Example = {
  a: 'a'
  [key: string]: string
}

declare const example: Example
const key1: string = 'a'
example[key1] = 'not a' // no error

declare const key2: 'a' | 'b'
example[key2] = 'not a' // error, as expected
//^^^^^^^^^^^
// Type '"not a"' is not assignable to type '"a"'.
🙁 Actual behavior

The index signature allows any string value to be assigned, ignoring the narrower type of a.

🙂 Expected behavior

Both property assignments in the above code should raise errors, for the same reason.

Additional information about the issue

This is a more generalized version of #60700. @MartinJohns helped me realize that type parameters need not be involved.

Here's another pair of examples (1, 2) which I expected to be reasoned through similarly:

type WiderType = { a?: string, b?: string }
type Example = { a: 'a' } & WiderType
declare const example: Example
declare const key: keyof Example
example[key] = 'not a'
//^^^^^^^^^^
// Type '"not a"' is not assignable to type '"a"'.
type WiderType = { [key: string]: string }
type Example = { a: 'a' } & WiderType
declare const example: Example
declare const key: keyof Example
example[key] = 'not a' // no error

In both cases Example carries with it the information that the property a must have a value assignable to 'a' (as can be seen with example.a = 'not a'). But this is not enforced when assigning to dynamic property using a key whose type matches the index signature.

Here's another example which does produce the error I expect:

type WiderType = { [key: string | symbol]: string }
type Example = { [key: string]: 'a' } & WiderType

declare const example: Example
declare const key: string | symbol
example[key] = 'not a' // error, as expected
//^^^^^^^^^^
// Type '"not a"' is not assignable to type '"a"'.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne mit den verlinkten TypeScript Playground-Beispielen und vergleiche indizierte Zuweisungen über String-Schlüssel mit direkten Eigenschaftszuweisungen. Verfolge, wie der Type Checker den beschreibbaren Typ für den indizierten Zugriff bestimmt, und ergänze Tests, die zeigen, dass enger deklarierte Eigenschaften erzwungen werden; fertig ist es, wenn beide gemeldeten Beispiele "not a" ablehnen, während die bestehenden gültigen Fälle weiterhin akzeptiert werden.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
typescript
Bereich
compilers
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.