microsoft / microsoft/TypeScript
"Lookup" Type Broken When Using Generics
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Go
- Sterne
- 111k
- Forks
- 14.3k
- Ø Merge
- 2 T. 4 Std.
- Gemergte PRs (30 T.)
- 132
Beschreibung
🔎 Search Terms
"nested lookup with generic", "type lookup with generic"
🕗 Version & Regression Information
- For
doesNotWork1, this changed between versions3.9.7and4.0.5. - For other "not working" examples, this is the behavior in every version I tried, and I reviewed the FAQ for entries about generics within lookup tables.
⏯ Playground Link
💻 Code
interface WithCommon {
field1: number;
field2: string;
}
interface WithSpecial extends WithCommon {
special: number;
}
interface SpecialLookup {
special: WithSpecial;
}
interface CommonLookup extends SpecialLookup {
common: WithCommon;
}
type Lookup<Name extends keyof CommonLookup> = {
[K in keyof CommonLookup[Name]]?: CommonLookup[Name][K];
};
// NOTE: this is broken even with `keyof CommonLookup` — key `special` has to be removed to see current error return since with `CommonLookup` we do detect that `special` is not a shared key of all members
function someName<K extends keyof SpecialLookup>(): void {
const works1: Lookup<'special'> = {
field1: 1,
field2: 'common',
special: 203,
};
const works2: Lookup<'common'> = {
field1: 5,
field2: 'something',
// correctly finds that this field should not be there
special: 32,
};
// expectation is that `undefined` should be allowed due to property types showing that it should be
// NOTE: this *was* working in v3.9.7
const doesNotWork1: Lookup<K> = {
// (property) special?: CommonLookup[K]["special"] | undefined — so at minimum this should be resolve to `undefined` since `never | undefined` resolves to `undefined`...
special: undefined,
field1: undefined,
field2: undefined,
};
// expectation is that this would be able to correctly identify fields in common for this specific set of keys
// NOTE: this does not work in any version available in playground
const doesNotWork2: Lookup<K> = {
special: 1004,
}
// expectation is that this would be able to correctly identify fields in common with all examples
// NOTE: this does not work in any version available in playground
const doesNotWork3: Lookup<K> = {
field1: 15,
field2: 'another'
}
}
🙁 Actual behavior
When using a generic as the input to a "lookup" type, we should be able to correctly type the common fields of the "looked-up" interfaces.
What is interesting here is that we appear to get correct behavior from "code completion" (i.e. special is correctly typed as a property of Lookup<K> with type CommonLookup[K]["special"] | undefined), but actually setting the presented type value doesn't work.
🙂 Expected behavior
We should get correct typing for the generic Lookup<K> type:
doesNotWork1should allowundefinedas a value since field type evaluates toCommonLookup[K][Field] | undefined.doesNotWork2should allownumberas value for fieldspecialsince all interfaces withinkeyof SpecialLookuphavespecial: numberon the interface.doesNotWork3should allow values forfield1andfield2for the same reason asdoesNotWork2.
Additional information about the issue
As I called out in my NOTE within the code example, this is also broken in a "simpler" example where the generic is K extends keyof CommonLookup. I presented the above code example because it is the most similar to my use case and I wasn't sure if fixing the "simpler" case would also fix the one where we are choosing a smaller key set.
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne mit dem verlinkten TypeScript Playground und reproduziere die Beispiele doesNotWork1–3 über die angegebenen Compiler-Versionen hinweg. Verfolge das Type-Checking-Verhalten bei generischen Lookups und überprüfe anschließend, dass die erwarteten Zuweisungen von undefined und gemeinsamen Feldern typgeprüft werden, ohne ungültige Felder zuzulassen.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- typescript
- Bereich
- compilers
- Issue-Typ
- Bug
- Schwierigkeit
- 5/5
- Geschätzter Aufwand
- Über eine Woche
- Aktivitätsstatus
- Veraltet
- Klarheit
- Klar beschrieben
- Anfängerfreundlichkeit
- 35/100