microsoft / microsoft/TypeScript
Writes to indexed access of an index signature are not sufficiently constrained
Nessuno ha ancora preso questa issue.
- 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
💻 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
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- 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