microsoft / microsoft/TypeScript

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

Aperta
#60,703 5 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Experimentation Needed Suggestion
Lingua principale
Go
Stelle
111k
Fork
14.3k
Merge medio
2g 4h
PR unite (30g)
132

Descrizione

🔎 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"'.

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia con gli esempi collegati di TypeScript Playground e confronta le assegnazioni indicizzate tramite chiavi stringa con le assegnazioni dirette delle proprietà. Traccia il modo in cui il Type Checker determina il tipo scrivibile per l'accesso indicizzato, quindi aggiungi una copertura che dimostri che le proprietà dichiarate più ristrette vengono applicate; il lavoro è completo quando entrambi gli esempi segnalati rifiutano "not a" mentre i casi validi esistenti continuano a essere accettati.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
typescript
Ambito
compilers
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Specificata chiaramente
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.