Comment puis-je empêcher le message d'erreur “l'Indice de signature de type d'objet a implicitement un "tout" type” lors de la compilation de texte dactylographié avec noImplicitAny indicateur activé?
J'ai toujours compiler Tapuscrit avec le drapeau --noImplicitAny. Cela a du sens que je veux que mon vérification de type à être aussi serrée que possible.
Mon problème est que, avec le code suivant, je reçois l'erreur Index signature of object type implicitly has an 'any' type
:
interface ISomeObject {
firstKey: string;
secondKey: string;
thirdKey: string;
}
let someObject: ISomeObject = {
firstKey: 'firstValue',
secondKey: 'secondValue',
thirdKey: 'thirdValue'
};
let key: string = 'secondKey';
let secondValue: string = someObject[key];
Important à noter est que l'idée est que la variable clé qui vient de quelque part d'autre dans l'application et peut être l'une des clés de l'objet.
J'ai essayé explicitement le casting du type:
let secondValue: string = <string>someObject[key];
Ou est mon scénario tout simplement pas possible avec --noImplicitAny
?
OriginalL'auteur Jasper Schulte | 2015-10-06
Vous devez vous connecter pour publier un commentaire.
L'ajout d'un index signature permettra à la Machine de savoir de quel type doit être.
Dans votre cas, ce serait
[key: string]: string;
Cependant, cette applique également à tous les types de propriété correspond à l'index de la signature. Étant donné que toutes les propriétés sont un
string
il fonctionne.Edit:
Si les types ne correspondent pas, un type d'union peuvent être utilisés
[key: string]: string|IOtherObject;
Avec les types d'union, c'est mieux si vous laissez la Machine de déduire le type au lieu de le définir.
Bien que ce que peut obtenir un peu désordonné si vous avez beaucoup de différents types dans l'index de signatures. L'alternative qui consiste à utiliser
any
dans la signature.[key: string]: any;
Alors vous devez jeter les types comme vous l'avez fait ci-dessus.Nope, il y a un moyen, mise à jour de la réponse.
Merci! La combinaison de n'importe quel type de concert avec le moulage d'un type par cas semble un vendu de chemin à faire.
OriginalL'auteur thoughtrepo
Une autre façon d'éviter l'erreur est d'utiliser la fonte comme ceci:
let secondValue: string = (<any>someObject)[key];
(Note de la parenthèse)
Le seul problème, c'est que ce n'est pas de type-safe plus, que vous êtes casting pour
any
. Mais vous pouvez toujours jeté en arrière pour le type correct.ps: je suis en utilisant le tapuscrit 1.7, vous ne savez pas sur les versions précédentes.
let secondValue: string = (someObject as any)[key];
OriginalL'auteur Pedro Villa Verde
Tapuscrit 2.1 introduit élégante manière de traiter ce problème.
Nous pouvons accéder à toutes les propriété de l'objet de nom lors de la phase de compilation par
keyof
mot-clé (voir changelog).Vous avez seulement besoin de remplacer
string
type de variable aveckeyof ISomeObject
.Maintenant compilateur sait
key
variable est autorisé à contenir que les noms de propriété deISomeObject
.Exemple complet:
De code en direct sur typescriptlang.org (set
noImplicitAny
option)Lecture avec plus de
keyof
usages.key
commeconst key = (keyof ISomeObject)
= 'deuxième Touche'+''il génère ts2322 erreur
OriginalL'auteur Piotr Lewandowski
Suivantes tsconfig de réglage va vous permettre d'ignorer ces erreurs - attribuez la valeur true.
Je suis en désaccord c'est exactement ce que cette option a été faite pour : Permettre supports de notation avec
--noImplicitAny
. Match parfaitement op question.Je suis d'accord avec @Ghetolay . C'est aussi la seule option si la modification de l'interface n'est pas possible. Par exemple, avec des interfaces internes comme
XMLHttpRequest
.Je suis également d'accord avec @Ghetolay. Je suis curieux de voir comment ce est qualitativement différent de Pedro Villa Verde de la réponse (en dehors du fait que le code est moins moche). Nous savons tous que l'accès à une propriété de l'objet à l'aide d'une chaîne de caractères doit être évitée si possible, mais il parfois de jouir de cette liberté, tout en sachant les risques.
C'est juste compromis. Choisissez ce que vous aimez: moins d'erreur de surface et stricte de l'indice de l'accès, ou avoir plus de surface pour les erreurs et accéder facilement aux inconnus indices. Le TS2.1
keyof
opérateur peut aider à garder tout ce strict, voir Piotr réponse!OriginalL'auteur Scott Munro
Le "keyof' solution mentionnée ci-dessus fonctionne. Mais si la variable est utilisée qu'une seule fois.e.g en boucle par le biais d'un objet, etc, vous pouvez également catalogué.
OriginalL'auteur Karna
Similaire à @Piotr Lewandowski réponse, mais dans un
forEach
:OriginalL'auteur Steve Brush
utilisation
keyof typeof
OriginalL'auteur alsotang
Déclarer l'objet de ce genre.
OriginalL'auteur Supun Dharmarathne
Pas indexer? Ensuite, faire votre propre!
J'ai globalement défini cela comme un moyen facile de définir un objet de la signature.
T
peut êtreany
si nécessaire:Je viens de l'ajouter
indexer
en tant que membre de la classe.Donc je me retrouve avec ceci:
Avantage de ceci est que vous obtenez le bon type de retour - de nombreuses solutions qui utilisent
<any>
perdrez le taper pour vous. Rappelez-vous ce n'effectue pas de vérification runtime. Vous aurez toujours besoin de vérifier si quelque chose existe, si vous ne savez pas qu'il existe.Si vous souhaitez être trop prudents, et que vous utilisez
strict
cela peut vous révéler tous les lieux que vous devrez peut-être n'explicite pas défini vérifier:Je n'ai pas l'habitude de trouver ce nécessaire car si j'ai comme une propriété de chaîne à partir de quelque part j'ai l'habitude de savoir qu'il est valide.
J'ai trouvé cette méthode particulièrement utile si j'ai beaucoup de code pour accéder à l'indexeur et le typage peut être changé en un seul lieu.
Note: je suis en utilisant
strict
mode, et launknown
est certainement nécessaire.Le code compilé sera juste
indexer = this
, c'est donc très similaire à lorsque la machine crée_this = this
pour vous.OriginalL'auteur Simon_Weaver
Créer une interface pour définir le " indexeur de l'interface
Puis de créer votre objet avec celui de l'indice.
Remarque: cela permettra de toujours avoir les mêmes problèmes que d'autres réponses que nous avons décrite à l'égard de l'application, le type de chaque élément, mais c'est souvent exactement ce que vous voulez.
Vous pouvez faire le paramètre de type générique quel que soit votre besoin :
ObjectIndexer< Dog | Cat>
Tapuscrit De L'Aire De Jeux
Vous pouvez même l'utiliser dans un générique contrainte lors de la définition d'un type générique:
export class SmartFormGroup<T extends IndexableObject<any>> extends FormGroup
Puis
T
à l'intérieur de la classe peuvent être indexés 🙂Dictionary
qui représente{ [key: string]: T }
, mais si jamais il y est merci d'éditer cette question à supprimer monObjectIndexer
.OriginalL'auteur Simon_Weaver
La solution la plus simple que j'ai pu trouver à l'aide de Tapuscrit 3.1 en 3 étapes:
1) Faire une interface
2) Faire une copie dactylographiée
3) Utiliser n'importe où (JSX inclus)
OriginalL'auteur Artokun
À aujourd'hui, la meilleure solution est de déclarer les types. Comme
OriginalL'auteur Artsiom Tymchanka