microsoft / microsoft/TypeScript
Template Literal Types derived from the type keys cannot be used as Indexed Access Types in generic contexts
Personne n'a encore pris cette issue.
- Langage dominant
- Go
- Étoiles
- 111k
- Forks
- 14.4k
- Merge moyen
- 1 j 19 h
- PR mergées (30 j)
- 117
Description
🔎 Search Terms
template literal, indexed access, keyof, key of
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about indexed access.
⏯ Playground Link
💻 Code
// Types with numeric keys.
type A = [1];
type B = 1[];
type C = { [key: number]: 1 };
type D = { 0: 1 };
// Allowed indexed access types.
type Allowed = [A[0], A['0'], A[number], A[`${number}`], B[0], B['0'], B[number], B[`${number}`], C[0], C['0'], C[number], C[`${number}`], D[0], D['0']];
// Disallowed indexed access types.
type Disallowed = [A[string], B[string], C[string], D[string], D[number], D[`${number}`]];
type NotAnIssue<T extends object> = T[`${keyof T}`];
type Issue<T extends object> = T[`${keyof T & (string | number | bigint | boolean | null | undefined)}`];
type CompactIssue<T extends object> = T[`${Exclude<keyof T, symbol>}`];
🙁 Actual behavior
The template type literal generated from keyof T cannot be used as an indexed access type for T.
🙂 Expected behavior
The template type literal generated from keyof T or its restriction can be used as an indexed access type for T, since it is restricted to be a stringified version of the key type, which should behave exactly the same as the key type in this context.
Additional information about the issue
All object types with numeric keys can be accessed with the string version of that key. However, the compiler does not acknowledge this fact in the case of generics with proper restrictions on the type.
Using `${keyof T}` directly is prohibited because template literal types cannot be constructed from symbol types. However, if the type is restricted to the allowed string | number | bigint | boolean | null | undefined, TypeScript is still refusing to use keyof T for indexed access.
The issue does not happen with definite (non-generic) types and the issue also does not occur if `${Exclude<keyof T, symbol>}` is replaced with Exclude<keyof T, symbol> (which is still a problem for other use cases).
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Reproduisez les cas génériques d'accès indexé dans le TypeScript Playground lié, en les comparant aux exemples autorisés et non génériques de l'issue. Suivez le traitement par le compilateur des types littéraux de modèle dérivés de keyof T ; le travail est terminé lorsque les formes restreintes de littéraux de modèle sont acceptées comme types d'accès indexé sans réintroduire les cas interdits indiqués.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- typescript
- Domaine
- compilers
- Type d'issue
- Bug
- Difficulté
- 5/5
- Temps estimé
- Plus d'une semaine
- Activité
- À l'abandon
- Clarté
- Plutôt claire
- Accessibilité débutants
- 32/100