microsoft / microsoft/TypeScript
Strange behavior of types while using nested mapped types and generics
Nessuno ha ancora preso questa issue.
- Lingua principale
- Go
- Stelle
- 111k
- Fork
- 14.4k
- Merge medio
- 1g 19h
- PR unite (30g)
- 117
Descrizione
Bug Report
I got two differents typings while nesting objects using some object-builder functions and generic optional typings, keeping it quite basic.
These two typings show up in a one-in-two pattern as we dig into the nested objects.
The second one matches with the type of the object-builder.
It can be a misuse of mine so let me know ...
🔎 Search Terms
- mapped type
- nested
- partial optional
- generic
🕗 Version & Regression Information
Typescript versions 5.1.4 & 5.2.0-dev.20230625 & 4.1.6
Just discovered it, so AFAIK this is not a regression.
⏯ Playground Link
💻 Code
type OptionalyProped<OPTL extends number> = { optlValue?: OPTL }
export const optionalyProped = <OPTL extends number>(proped: OptionalyProped<OPTL>): OptionalyProped<OPTL> => proped
type ObjectOfProped<T extends { [key: string]: ObjectOrProped }> = { structure: T }
export const objectOfProped = <OBJ extends { [key: string]: ObjectOrProped }>(
objectOf: ObjectOfProped<OBJ>
): ObjectOfProped<OBJ> => objectOf
type ObjectOrProped = ObjectOfProped<any> | OptionalyProped<any>
const test = objectOfProped({
structure: {
n: optionalyProped({}),
p: optionalyProped({ optlValue: 21}),
o: objectOfProped({
structure: {
n: optionalyProped({}),
p: optionalyProped({ optlValue: 21}),
o: objectOfProped({
structure: {
n: optionalyProped({}),
p: optionalyProped({ optlValue: 21}),
o: objectOfProped({
structure: {
n: optionalyProped({}),
p: optionalyProped({ optlValue: 21}),
},
}),
},
}),
},
}),
},
})
const n = optionalyProped({ }) // typed: OptionalyProped<number>
const p = optionalyProped({ optlValue: 21 }) // typed: OptionalyProped<21>
🙁 Actual behavior
typeof test = ObjectOfProped<{
n: OptionalyProped<any>; // first behavior
p: OptionalyProped<number>;
o: ObjectOfProped<{
n: OptionalyProped<number>; // second behavior (legit one)
p: OptionalyProped<21>;
o: ObjectOfProped<{
n: OptionalyProped<any>;
p: OptionalyProped<number>;
o: ObjectOfProped<{
n: OptionalyProped<number>;
p: OptionalyProped<21>;
}>;
}>;
}>;
}>
🙂 Expected behavior
typeof test = ObjectOfProped<{
n: OptionalyProped<number>; // always
p: OptionalyProped<21>;
o: ObjectOfProped<{
n: OptionalyProped<number>; // the same
p: OptionalyProped<21>;
o: ObjectOfProped<{
n: OptionalyProped<number>; // type
p: OptionalyProped<21>;
o: ObjectOfProped<{
n: OptionalyProped<number>;
p: OptionalyProped<21>;
}>;
}>;
}>;
}>
Thanks
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 il link fornito a TypeScript Playground e con l'esempio di object-builder annidato, confrontando il tipo inferito di test con le dichiarazioni autonome di n e p. Traccia il modo in cui le chiamate generiche annidate inferiscono i tipi OptionalyProped; il lavoro è completato quando le proprietà n annidate inferiscono costantemente OptionalyProped<number> e le proprietà p mantengono OptionalyProped<21>.
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
- Abbastanza chiara
- Idoneità per principianti
- 35/100