Typescript: Capacité de suralimenter TS et d'ignorer les erreurs spécifiques du développeur

Créé le 30 juin 2016  ·  150Commentaires  ·  Source: microsoft/TypeScript

Un développeur devrait pouvoir ajouter un commentaire au-dessus d'une erreur ts telle que

/// TS_IGNORE
let a:string = 1

et que le compilateur ne signale pas cette erreur...
il existe certains scénarios que le développeur connaît le mieux et souhaite faire taire les rapports d'erreur.

un peu comme :n'importe

Cordialement

Sean

Fixed Suggestion

Commentaire le plus utile

Il suffit de le lancer (le casting n'est pas un terme officiel, mais le même concept)

const foo: string = 7 as any;

C'est ça que tu cherches ?

Tous les 150 commentaires

D'accord. Envie de quelque chose comme le @SuppressWarnings Java, en particulier pour le cas décrit ici :

Ce qui suit:

const typeMetadataKey = Symbol('type');

function type(name: string): PropertyDescriptor {
 return Reflect.metadata(typeMetadataKey, name);
}

Produit l'erreur : Unable to resolve signature of class decorator when called as an expression. .

Lorsqu'il est utilisé comme ci-dessous :

class Person {
  @type('string')
  firstName: string;
}

Le décorateur fonctionne comme prévu et compilera mais donnera l'erreur ci-dessus.

Si vous avez des idées sur la façon dont cela pourrait être résolu, n'hésitez pas à creuser si quelqu'un souhaite indiquer la bonne direction.

Il suffit de le lancer (le casting n'est pas un terme officiel, mais le même concept)

const foo: string = 7 as any;

C'est ça que tu cherches ?

J'ai juste donné un exemple, pas vraiment un cas (je sais tout sur le casting), j'ai d'autres cas comme
super étant appelé après la première ligne du constructeur et d'autres problèmes ...

  • rendra la transition vers TS plus facile à partir de JS + parfois vous changez une bibliothèque et obtenez des tonnes d'erreurs et vous voulez juste nettoyer les choses comme vous le savez en tant que développeur pour la raison ...

c'est une caractéristique importante

Donc quelque chose comme // tslint:disable ?
Peut-être même vous laisser activer/désactiver les contrôles spécifiques effectués par tsc ?
_ex:_ const FooBar: string = 'rozzzly'; // tslint:disable-line camelcase

ce serait génial...

Je ne sais pas... Je pense que cela pourrait sortir du cadre de tsc . C'est à ça que servent les linters.

il faut pouvoir "la fermer" :)

Je pense qu'il y a lieu de plaider en faveur de la suppression des erreurs/avertissements sur les fonctionnalités "expérimentales", comme les décorateurs, où l'API est un peu volatile et les erreurs peuvent ne pas toujours être exactes. Vous obtenez une version (très spécifique) de cela en utilisant simplement le champ tsconfig "experimentalDecorators", mais il ne supprime qu'un seul type d'avertissement.

Pour jouer mon propre avocat du diable, cela pourrait encourager les nouveaux utilisateurs de TypeScript à supprimer les avertissements qu'ils ne comprennent pas au lieu d'apprendre pourquoi l'avertissement se produit. Et avec les fonctionnalités expérimentales, tout le monde est en quelque sorte un nouvel utilisateur - avoir la possibilité de supprimer les erreurs pourrait rendre les utilisateurs complaisants avec les bogues dans les nouvelles fonctionnalités, au lieu d'ouvrir des problèmes.

En fin de compte, je veux toujours que ma sortie Syntastic soit propre. Ce qui signifie supprimer l'erreur. Bien sûr, ce serait _après_ que j'ouvre le problème pour un éventuel bug et essaie d'en savoir plus. ;)

Le problème avec « la fermer » est que vous ne savez pas ce que vous en retirez. alors est-ce que let a:string = 1 un number ou un string ?, et s'il y a une autre déclaration de a , fusionne-t-elle ou non ? et si quelqu'un capturait le type de cette variable, par exemple return {a} ; , devraient-ils être attribuables à { a : number } ou { a: string } , ou les deux.

une chose fondamentale, les erreurs sont toutes ignobles. les erreurs ne bloquent pas la génération des sorties, ni l'outillage.

Il existe différents mécanismes pour vous permettre de supprimer la vérification de certaines parties de votre code, par exemple any , les assertions de type (casts) et la déclaration ambiante.

ainsi, par exemple, si vous avez une bibliothèque qui a une définition « invalide », vous pouvez simplement la supprimer et la remplacer par declare module "blah" { export = any } . ou declare var $: any et vous êtes prêt à partir.

Comme je réponds habituellement à ces demandes, je pense que votre problème n'est pas de supprimer l'erreur. le vrai problème est que vous avez une erreur que vous ne trouvez pas utile. supprimer qui ne résout pas le problème sous-jacent, il le couvre simplement et a des ramifications d'un état incohérent sans avertissement. La bonne solution est de savoir quelle est l'erreur que vous obtenez ? de quelle bibliothèque s'agit-il ? et pourquoi le compilateur vous donne une erreur inutile ...

Et pour cela, nous avons besoin d'en savoir plus sur votre cas d'utilisation.

Nous avons travaillé sur TS 2.0 pour résoudre certains de ces problèmes sous-jacents, par exemple ;

il suffit d'utiliser n'importe lequel, c'est comme ça que "la fermer", le mérite de le faire (ou en fait son absence) est une question différente

let x: PieInTheSky = <any> 'cake is a lie';

ok mais encore une fois, le problème n'est pas spécifiquement sur le casting

<any> vous offre un javascript vanille avec une liberté à 100% de toutes les choses ennuyeuses de TypeScript, alors de quoi d'autre avez-vous besoin ?

dans mon cas, j'appelle super pas comme première ligne de constructeur et je dois calmer l'erreur

Au lieu d'essayer de le forcer à accepter un anti-modèle, pourquoi ne pas écrire essayez quelque chose comme ceci :

_ ClassA.ts _

class A {
    constructor() {
        this.init();
    }
    protected init() {
        // does nothing by itself
    }
}

_ ClassB.ts _

class B extends A {
    constructor() {
        super();
        console.log('rest of code from B\'s constructor');
    }
    protected init() {
        console.log('this runs before the rest of code from B\'s constructor');
    }
}

C'est ce qui rend le tapuscrit si génial, _et aussi ennuyeux_. Cela vous oblige à écrire un meilleur code et cela fait de vous un meilleur développeur. Convertir un projet n'est pas amusant ; vous pourriez considérer qu'il s'agit d'une « initiation » d'un développeur ou peut-être d'un « essai par le feu ». :rire: Mais vous apprenez beaucoup, et ça vaut vraiment le coup à mon humble avis.

dans mon cas, j'appelle super pas comme première ligne de constructeur et je dois calmer l'erreur

Et rendez votre code incompatible avec ES6... C'est exactement pourquoi le but principal de TypeScript est de vous retirer 👣 :gun: de vos mains.

Si TypeScript n'interprète pas quelque chose correctement, il doit être corrigé plutôt que "contourné". Maintenant, il y a quelques choses où TypeScript agit plus comme un linter et il n'y a pas encore de concept d'"erreur" par rapport à "avertissement". Je peux voir des avertissements de suppression quand ils arrivent. Des choses comme le code après le retour et les paramètres inutilisés devraient être des avertissements à mon avis, car ils sont syntaxiquement corrects (bien que stupides).

voici un autre cas où j'aimerais avoir cette fonctionnalité:

interface Animal {
  numberOfLegs: number;
  // a gazillion more properties
}

class Dog implements Animal {
  breed: string;

  constructor(animal: Animal, breed: string) {
    Object.assign(this, animal);
    this.breed = breed;
  }
}

En ce moment, il y a une erreur de ts :

[ts] La classe 'Chien' implémente incorrectement l'interface 'Animal'
La propriété 'numberOfLegs' est manquante dans le type 'Chien'

Comme vous pouvez le voir, le compilateur est totalement faux, mais je ne veux pas (et je ne devrais pas être obligé de) copier toutes les propriétés de l'interface juste pour le compilateur.

@DethAriel Fondamentalement, ce que vous demandez est un moyen d'exprimer les effets secondaires post-condition dans le système de type. C'est intéressant, mais j'ai le sentiment que cela conduirait à un code terriblement alambiqué.

@aluanhaddad Oui , je comprends tout à fait. Mais encore, je ne vois pas de solution de contournement non laide pour cela, à l'exception du copier-coller des membres de l'interface, ce qui n'est pour le moins pas idéal. C'est pourquoi je pense qu'avoir la possibilité de fermer la sortie d'erreur du compilateur est logique - nous sommes tous des gens intelligents ici, et le compilateur doit nous faire confiance lorsque nous lui disons de

Utilisez simplement un combo interface + classe

interface Animal {
  numberOfLegs: number;
  // a gazillion more properties
}

interface Dog extends Animal {
}

class Dog  {
  breed: string;

  constructor(animal: Animal, breed: string) {
    Object.assign(this, animal);
    this.breed = breed;
  }
}

Merci ,

Que faire si l'erreur ne peut pas être <any> résolue ?

J'utilise la syntaxe de liaison expérimentale comme indiqué ici https://github.com/Microsoft/TypeScript/issues/3508 et en plus de ne pas l'utiliser, je ne parviens pas à faire en sorte que le compilateur ignore l'erreur sur chaque ligne avant chaque :: Opérateur TS1128: Declaration or statement expected )

J'utilise la syntaxe de liaison expérimentale

c'est vraiment plus que de rejeter un avertissement. L'analyseur ne le prend pas en charge, donc l'arbre résultant est complètement faux, toutes les fonctionnalités du compilateur à partir de ce point ne fonctionneront pas, donc pas d'inférence de type, pas de vérification de compatibilité, pas de formatage, pas de complétion, rien. vous feriez donc mieux d'ignorer toutes les erreurs ou de simplement travailler dans un fichier .js.

Je convertis actuellement un énorme projet JS en script dactylographié et après avoir effectué la conversion lorsque j'exécute la commande gulp build je vois environ 2000 erreurs TS lors de la compilation et la majorité des erreurs sont liées à une propriété non définie sur une classe ou un module non défini. Je pense qu'il doit y avoir un moyen de supprimer ces types d'erreurs lorsque les fichiers JS de sortie sont générés.

C'est exactement mon cas aussi, je convertis une application construite avec une conception de modules en tant que propriétés pré-ES6, j'ai donc un ÉNORME objet global app.namespace1.namespace2.something.views.view -like.

J'en réécris une partie et je m'appuie sur l'objet global app.* et ses différents sous-éléments dans mon code. Tout ce que je reçois, c'est une masse d'avertissements "Impossible de trouver l'espace de noms 'app'".

J'ai refactorisé toutes mes dépendances globales en un globalProxy.ts, c'est donc le seul endroit où je reçois les avertissements, mais ce serait IMPRESSIONNANT d'ajouter un //TS-NO-WARNINGS en haut de ce fichier pour nettoyer la console des messages évidents...

Les erreurs TS ne bloquent pas la génération de code. Vous pouvez choisir de les ignorer, mais ce qu'ils vous disent, c'est que le compilateur ne peut pas affirmer l'exactitude de votre code.

@zeeshanjan82 pourquoi ne pas utiliser --allowJs et migrer fichier par fichier ? Avec cette configuration, vous n'obtiendrez pas d'erreurs de type à partir des sources JavaScript. Vous pouvez également utiliser une déclaration de caractère générique ambiant pour supprimer les erreurs de résolution de module telles que
_globals.d.ts_

declare module '*';

Voici un autre cas d'utilisation pour la suppression des erreurs.

Les responsables de la bibliothèque du moment ont oublié d'ajouter isoWeek comme chaîne valide au paramètre enum pour les méthodes startOf et endOf . Cela a été corrigé dans une version ultérieure, mais ce faisant, ils ont complètement remanié la façon dont ces unités sont gérées, ce qui entraînerait trop de remaniement de notre part.

Nous avons donc corrigé la version de moment en place, mais maintenant, nous ne pouvons essentiellement plus utiliser isoWeek cause des erreurs de lancement de TS. Donc coincé entre le marteau et l'enclume pour le moment.

vous pouvez simplement ajouter une copie locale. dire quelque chose d'aussi simple que :

// ./overrides/moment.d.ts
declare module "moment";
// tsconfig.json
{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es5",
        "baseUrl": ".",
        "paths": {
            "moment": ["overrides/moment.d.ts"]  // override definition for moment
        }
    }
}

maintenant, le compilateur vérifiera votre copie locale de override/moment.d.ts au lieu de celle fournie avec le package. évidemment, cela peut être une copie locale du fichier de déclaration de moment, ou un petit ensemble de choses dont vous avez besoin.

Je manque à la fois de temps et d'envie de maintenir mes propres définitions de frappe pour les bibliothèques tierces ;)

Je manque à la fois de temps et d'envie de maintenir mes propres définitions de frappe pour les bibliothèques tierces ;)

Et c'est parfaitement bien. utilisez simplement declare module "moment"; qui est l'équivalent de declare var $: any pour les modules, et le compilateur ne vous dérangera plus à ce sujet.

La suggestion de @mhegazy est très bonne. Cela vous prendra environ 20 secondes pour le faire. Soit dit en passant, en ce qui concerne le moment, ils ont oublié quelques unités que j'utilisais et ils étaient très disposés à accepter ma demande de tirage.

L'inconvénient de l'ajout de declare module "moment"; est que vous n'aurez plus aucune vérification de type IDE intellisense ou statique pour tout code lié au moment. Et les any qui surviennent ont tendance à se répandre dans le code environnant, arrêtant également de nombreuses vérifications statiques. C'est un lourd tribut à payer pour supprimer les erreurs liées à une seule valeur d'énumération problématique.

@aluanhaddad il y avait une pull request ouverte pour résoudre le problème, mais elle a été fermée en faveur d'un autre, qui a introduit des changements de rupture (et n'a toujours pas ajouté de support pour isoWeek ), donc je ne sais pas ce qui s'est passé là-bas .

Le fait est que ces problèmes ne manqueront pas de se poser plus fréquemment à l'avenir avec l'adoption d'Angular 2, etc. Un moyen de supprimer des erreurs particulières serait donc utile, je peux l'imaginer.

J'ai ce problème avec une bibliothèque principale de nœuds (net, nœud 6.9 LTS):

server = net.createServer({ pauseOnConnect: true }, function(connection) { ... }) 
// [ts] severity: 'Error'
message: 'Argument of type '{ pauseOnConnect: boolean; }' is not assignable to parameter of type '{ allowHalfOpen?: boolean; }'.
  Object literal may only specify known properties, and 'pauseOnConnect' does not exist in type '{ allowHalfOpen?: boolean; }'.'

Et aussi avec la bibliothèque ioredis :

var redis = new Redis(CONFIG.redis); 
// [ts] severity: 'Error'
message: 'Only a void function can be called with the 'new' keyword.'

Comme @yortus et @adamreisnz l'ont souligné, il s'agit d'un problème courant car les fichiers de définition ne sont pas toujours correctement mis à jour. En outre, si vous devez sacrifier les avantages de TS en utilisant declare module "x"; pourquoi utiliseriez-vous TS en premier lieu ?

Vous pouvez également augmenter le module avec les types qui manquent afin de ne pas perdre en intelligence.

Bon, quand j'écris :

if (typeof Symbol === "function" && Symbol.match) {
  // ...
}

Le compilateur dactylographié rapporte toujours une erreur Cannot find name 'Symbol' si target est es5 , bien que ce code fonctionne bien comme je m'y attendais.

Je suis donc d'accord pour dire que nous avons grandement besoin de directives de contrôle fonctionnant dans les lignes de commentaires.

declare var Symbol: any;

@gdh1995 @mhegazy Ou utilisez simplement le vrai correctif qui définit le drapeau lib sur es2015 .

@mhegazy Merci. Je trouve que ça marche bien :

declare var Symbol: {
  (description?: anyNotSymbol): symbol;
  readonly match: symbol;
};

@DanielRosenwasser Bien que es2015 ajoute ces fonctionnalités utiles, mon projet est limité pour être compatible avec es5 et alors Symbol devrait être évité dans d'autres fichiers.

Ce que je ne comprends pas maintenant, c'est que le compilateur TypeScript me donne des erreurs même lorsque j'ai écrit typeof Symbol === "function" . Aucun conseil?

Un cas que j'aimerais avoir à présenter est celui des dépendances moqueuses :

// Test.ts

// Component to test
import {ComponentToTest} from './ComponentToTest';

// Dependency of ComponentToTest to mock
import {Dependency} from './Dependency';

// Mock to replace it with
import {MockedDependency} from './MockedDependency';

Dependency = MockedDependency;

Ce code a l'effet souhaité de moquer la dépendance dans le composant testé, mais TypeScript renvoie un "Impossible d'affecter à 'Dépendance' évident car ce n'est pas une variable." Erreur.

Je suis sûr que la réponse sera que j'aboie dans le mauvais arbre et que je devrais utiliser quelque chose comme inject-loader mais d'après mon expérience, ces solutions A) sont pénibles à faire fonctionner/pas toujours travail et B) ne sont pas aussi simples que ci-dessus. Comme OP l'a mentionné, parfois le développeur sait mieux. Je sais que c'est une solution bidon mais cela fonctionne et j'aimerais que TS se taise dans ce cas.

Ce code a l'effet souhaité de moquer la dépendance dans le composant testé, mais TypeScript renvoie un "Impossible d'affecter à 'Dépendance' évident car ce n'est pas une variable." Erreur.

c'est une erreur dans ES6. Ainsi, dans le futur, lorsque les moteurs prendront en charge les modules ES6 de manière native, vos tests devront être réécrits.

Alternativement, vous pouvez faire en sorte que votre ComponentToTest accepte un argument pour Dependency , et vos tests peuvent le réussir, ou avoir un hook de test qui vous permet de remplacer la valeur de Dependency avant d'appeler des méthodes sur ComponentToTest .

c'est une erreur dans ES6. Ainsi, dans le futur, lorsque les moteurs prendront en charge les modules ES6 de manière native, vos tests devront être réécrits.

Ah d'accord, je vais le laisser tomber car cette exigence est tangentielle à ce problème.

Alternativement, vous pouvez faire en sorte que votre ComponentToTest accepte un argument pour Dependency, et vos tests peuvent réussir cela ...

Je pense que c'est ce que nous avons fini par faire. C'est juste assez nul de devoir redéfinir l'API d'une classe pour la rendre testable, mais je suppose que ce n'est pas du tout un problème unique à TS.

Merci pour le retour, @mhegazy

J'aimerais remplacer la vérification du type d'argument d'une fonction.

Mon cas d'utilisation est assez simple, j'ai une fonction comme celle-ci :

function isValidId(s: string): boolean {}

qui vérifient si une chaîne suit une règle.
Il est utilisé à la fois en interne et pour valider les entrées de l'utilisateur - j'aimerais écrire des tests pour voir s'il renvoie false lorsque l'utilisateur insère quelque chose qui n'est pas une chaîne.

À proprement parler, la fonction peut accepter n'importe quoi en entrée car elle est capable de le gérer, mais comme nous l'utilisons également en interne, j'aimerais spécifier que nous voulons une chaîne

Par conséquent, j'aimerais que quelque chose supprime l'erreur de format incorrect dans les tests

@rpadovani utilise simplement any :

expect(isValidId(78 as any)).toBe(false);

Je pourrais aussi l'utiliser. Nous avons une situation dans laquelle foo(bar: any, baz: any) est défini comme faisant partie d'un framework, mais dans certaines implémentations de foo, bar n'est pas utilisé. Lorsque la vérification des erreurs dactylographiées est activée, cela génère une erreur car une variable inutilisée est déclarée. Il doit être déclaré, car d'autres versions de foo, bar sont utilisées.

@benjaminabbitt Il semble que foo (_bar: any, baz: any) fonctionne pour vous : un nom commençant par "_" n'est pas forcé d'être utilisé.

Ajouter : Je pense que la possibilité de remplacer/ignorer les erreurs spéciales est importante.

Quelque chose de difficile ici est que les gens continuent de se présenter en disant qu'ils veulent supprimer les erreurs, publier des extraits de code et obtenir des solutions efficaces dans le code pour faire taire ces erreurs (ou découvrir que leur code a vraiment un problème). Il est difficile de concevoir cette fonctionnalité sans savoir à quoi ressemble une erreur vraiment problématique ou sans comprendre quelles sont les erreurs que les gens veulent supprimer dans le monde.

Quelle est la manière appropriée de gérer le code javascript tiers que nous souhaitons inclure dans nos projets ?

Considérez le scénario suivant. Il existe une énorme bibliothèque qui n'a pas été publiée sur npm et même si c'était le cas, l'utilisation de la bibliothèque telle quelle ferait en sorte que notre application transporte beaucoup de code mort (le tremblement des arbres ne peut pas aider car ils attachent tout à un objet).

Supposons que dans ce cas, cela ne vaut tout simplement pas la peine d'extraire ce morceau de code et de le publier dans npm. Quelles autres options avons-nous?

Dans ma tentative d'utiliser cette bibliothèque, j'ai extrait le code dont mon projet a besoin et je l'ai intégré au projet en tant que fichier dactylographié. Le problème avec ceci est que le script dactylographié vérifie ce fichier et donne maintenant beaucoup d'erreurs pour ce fichier.

Pour cette situation, ce serait bien d'avoir le commentaire /* ts:disable */ en haut afin que le script dactylographié sache que nous ne nous soucions pas des éventuelles erreurs dans le fichier.

Veuillez noter que mon projet ne commit plus aucun fichier javascript et même si c'était le cas, le processus de construction deviendrait plus compliqué en essayant d'intégrer un javascript dans le flux.

Quelqu'un a-t-il des conseils sur la façon de traiter le code javascript tiers qui doit être hébergé dans un projet dactylographié ?

Quelqu'un a-t-il des conseils sur la façon de traiter le code JavaScript tiers qui doit être hébergé dans un projet dactylographié ?

ne les migrez pas. laissez les fichiers .js tels quels. créez plutôt un fichier .d.ts pour eux. c'est à cela que servent les fichiers .d.ts.

le fichier .d.ts peut commencer par quelque chose d'aussi basique que :

declare var $: any;

puis ajoutez-y comme bon vous semble et au fur et à mesure que vos besoins évoluent.

C'est une bonne option si je commit des fichiers js. Existe-t-il d'autres options pour les projets qui ignorent les fichiers js ?

C'est une bonne option si je commit des fichiers js. Existe-t-il d'autres options pour les projets qui ignorent les fichiers js ?

Je ne suis pas sûr de comprendre la question. Les fichiers JS sont ignorés par défaut. vous acceptez donc d'ajouter des fichiers. encore une fois, ma recommandation est que, pour le code externe qui n'est pas le vôtre, ou pour le code hérité que vous n'avez pas l'intention de modifier, ne vous embêtez pas à le convertir en TS. commencez par écrire un fichier .d.ts pour eux. pour cela, commencez simplement, avec des any puis ajoutez au fur et à mesure.

J'aurais dû dire que les fichiers js ne sont pas validés dans le référentiel git, d'où la raison de mettre le code dans un fichier ts. Quoi qu'il en soit, je vais essayer de suivre la voie que vous avez mentionnée et de forcer la validation de ces fichiers js.

vous n'avez pas besoin de valider les fichiers .js. disons que vous utilisez une dépendance par exemple réagir. en général, vous n'engagerez pas react-0.12.0.js dans votre dépôt, mais vous souhaitez l'utiliser. normalement, vous l'incluriez dans une balise sccript d'un CDN par exemple. disons aussi que @types/react n'existe pas, ou que vous ne voulez pas l'utiliser. donc dans votre projet, ajoutez un nouveau fichier de déclaration, appelez-le declarations.d.ts et ajoutez :

declare module "react"; // just saying the module is of type any

cela indique au compilateur qu'il existe un module appelé "react" et qu'il l'utilisera simplement, sans avoir besoin d'inclure de fichiers .js.

Donc, si je veux utiliser un petit morceau de javascript (qui n'est pas disponible via npm/CDN) et que je décide de le valider dans ma base de code, j'ai 2 options :

Option 1 : Conservez le code d'origine sous forme .js fichier .d.ts pour gérer les types.

Je pense que cela ne fonctionne pas pour @jmlopez-rod car il ne veut pas valider de code javascript dans son référentiel, et même s'il le faisait, il a dit que cela rendrait son processus de construction compliqué.

Option 2 : Enveloppez le javascript dans dactylographié et traitez toutes les erreurs dactylographiées.

Cela contourne le "processus de construction compliqué" car il traitera le code comme un script dactylographié... mais nous avons maintenant des erreurs de dactylographe et nous sommes revenus à la discussion d'origine dans ce fil de discussion. S'agit-il d'un cas d'utilisation valide pour pouvoir désactiver les erreurs dactylographiées ?

Je pense que cela ne fonctionne pas pour @jmlopez-rod car il ne veut pas valider de code javascript dans son référentiel, et même s'il le faisait, il a dit que cela rendrait son processus de construction compliqué.

Je ne suis pas sûr de comprendre pourquoi cela complique votre processus de construction. vous avez un fichier "library.js" et "website.js" , vous décidez de déplacer "website.js" vers "website.ts", appelez simplement tsc website.ts --outFile website.js et maintenant nous sommes de retour où tout cela commencé avec deux fichiers .js. alors ne voyez pas pourquoi c'est plus compliqué qu'avant.. c'est juste une étape de construction supplémentaire en tête de chaîne.

Cela contourne le "processus de construction compliqué" car il traitera le code comme un script dactylographié... mais nous avons maintenant des erreurs de dactylographe et nous sommes revenus à la discussion d'origine dans ce fil de discussion. S'agit-il d'un cas d'utilisation valide pour pouvoir désactiver les erreurs dactylographiées ?

Je ne suis pas sûr de bien comprendre pourquoi vous avez décidé de basculer ce fichier vers ts et de l'intégrer à votre projet, de laisser les types de celui-ci s'écouler dans vos autres composants, de le construire avec votre code, tout en le maintenant à une norme différente.

Peut-être qu'un exemple serait utile ici. comme @RyanCavanaugh l'a noté , il me semble que tous ces problèmes ont des moyens bien définis d'informer le compilateur des types et d'éviter les erreurs au lieu de désactiver toutes les erreurs et de jeter le bébé avec l'eau du bain.

Je ne pouvais pas comprendre pourquoi cette déclaration ambiante ne fonctionnait pas pour moi.
j'ai déjà défini la définition des chemins vers le tsconfig.json comme ceci
"paths": { "js-xlsx": ["./xlsx.d.ts"] }
mais je rencontre toujours cette erreur de module non trouvé.
J'ai essayé d'ajouter 'fs', 'fs-extra' et que les bibliothèques 'js-xlsx' n'ont toutes répondu à mes déclarations ambiantes, castings ou ajout de types comme ici declare var $: any;
@mhegazy

vous n'avez pas besoin de valider les fichiers .js. disons que vous utilisez une dépendance par exemple réagir. généralement, vous ne validerez pas react-0.12.0.js dans votre référentiel, mais vous souhaitez l'utiliser. normalement, vous l'incluriez dans une balise sccript d'un CDN par exemple. disons aussi que @types/react n'existe pas ou que vous ne voulez pas l'utiliser. donc dans votre projet, ajoutez un nouveau fichier de déclaration, appelez-le declarations.d.ts et ajoutez :

déclarer le module "réagir" ; // juste en disant que le module est de type any
cela indique au compilateur qu'il existe un module appelé "react" et qu'il l'utilisera simplement, sans avoir besoin d'inclure de fichiers .js.

Au fait, je sais que la bibliothèque fs-extra a la définition de type comme @types/fs-extra et pour le js-xlsx nous avons les bibliothèques ts-xlsx mais c'est tellement bizarre que cette astuce ne fonctionne pas pour moi :(

Au fait, je sais que la bibliothèque fs-extra a la définition de type comme @types/fs-extra et pour le js-xlsx nous avons les bibliothèques ts-xlsx mais c'est tellement bizarre que cette astuce ne fonctionne pas pour moi :(

Je pense qu'il y a autre chose dans ton projet.

c:\test\9448>npm install @types/fs-extra
[email protected] c:\test\9448
`-- @types/[email protected]
  `-- @types/[email protected]

npm WARN [email protected] No description
npm WARN [email protected] No repository field.

c:\test\9448>type a.ts
import { rmdir } from "fs-extra";
rmdir("c:/test");

c:\test\9448>type tsconfig.json
{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es5"
    }
}
c:\test\9448>tsc --v
Version 2.2.0

c:\test\9448>tsc

c:\test\9448>echo %ERRORLEVEL%
0

oui peut-être mais, le problème principal que je ne pouvais pas comprendre est pourquoi je ne pouvais pas supprimer les avertissements du compilateur avec les méthodes données. Au fait, j'ai https://github.com/AngularClass/angular2-webpack-starter , base pour mon projet

Supprimer les erreurs ne signifie pas nécessairement introduire des anti-modèles.

Je reçois une erreur incorrecte,

error TS1005: '{' expected.

sur ce JSX parfaitement bien :

<motor-node ref      = 'menu'
    absoluteSize     = `0, ${this.MENU_BAR_HEIGHT}, 0`
    >
    {menu}
</motor-node>,

Il se plaint que la chaîne du modèle a besoin de { . Cela devrait idéalement être corrigé, mais d'ici là, j'aimerais pouvoir supprimer l'erreur pour une bonne raison .

@trusktr , cette erreur est une erreur d'analyse. le supprimer ne change pas le fait que le compilateur ne comprend pas le code à partir de ce point, et la forme du reste du fichier est dans un état indéfini. cela signifie que même si cette erreur est étouffée, les types inférés, ainsi que d'autres erreurs générées dans ce fichier ou d'autres ne sont pas corrects.

Cela dit. Selon la spécification JSX :

JSXAttributeValue :

" JSXDoubleStringCharactersopt "
' JSXSingleStringCharactersopt '
{ AffectationExpression }
Élément JSX

Je crains donc que l'erreur ne soit correcte et qu'un attribut JSX ne puisse pas avoir de littéral de modèle de chaîne. vous pouvez utiliser absolteSize = {...} place

cette erreur est une erreur d'analyse

Oui, c'est pourquoi il devrait être corrigé.

La sortie est absoluteSize: "0, " + this.MENU_BAR_HEIGHT + ", 0" , ce qui me dit que le compilateur va très bien.

Oh. Désolé alors. J'ai mal compris votre commentaire. Je pensais que vous vouliez que l'erreur soit réduite au silence.

Je l'ai fait, mais vous avez raison, je devrais peut-être mieux vivre en ajoutant simplement {} .

Dans TS 2.1 (VS2017 RC), nous recevons des avertissements signalés provenant du dossier des fichiers JS des bibliothèques (situés dans / Scripts), comme TS7027. Ce serait bien de pouvoir supprimer les avertissements/erreurs des fichiers de bibliothèque ou au moins de les prendre en charge dans une sorte de fichier de suppression global (similaire à C# GlobalSupressions.cs)

Dans TS 2.1 (VS2017 RC), nous recevons des avertissements signalés provenant du dossier des fichiers JS des bibliothèques (situés dans / Scripts), comme TS7027.

Pour le code inaccessible (TS 7027), définissez --allowUnreachableCode ou définissez-le dans votre tsconfig.json .

Mais est-il possible de l'appliquer uniquement aux fichiers de bibliothèque. Parce que pour "mon code" j'en ai besoin !

en utilisant --alowJs cela devient votre code. le compilateur va l'aspirer, le transpiler vers la cible suggérée, le concaténera si vous utilisez --outFile .. c'est juste qu'il a une extension .js. s'il s'agit d'un code "bibliothèque", je recommanderais de créer un fichier .d.ts pour celui-ci et de l'inclure à la place.

Je ne suis pas au courant que nous ayons activé --allowJs - dans VS2015, exactement le même projet ne gribouille pas les fichiers jquery.js, react.js assis dans les scripts (et en fait référencés uniquement à partir de la page html par

let { value } = browser.waitForPromise(() => {
    return browser.executeAsync(function (method, name, resolve) {
        require(['patron.Locator/patron.Locator.Manager'], function (locator) {
            resolve(result);
        });
    }, method, name);
});

Dans mon cas, la première ligne écrite en TypeScript, la deuxième ligne écrite en JavaScript. Ils sont exécutés dans des contextes différents et je ne souhaite pas modifier le code JavaScript.
Donc, nous avons besoin d'une nouvelle option comme /* ts-disable */ /* ts-enable */ (comme eslint)

Dans mon cas, la première ligne écrite en TypeScript, la deuxième ligne écrite en JavaScript. Ils sont exécutés dans des contextes différents et je ne souhaite pas modifier le code JavaScript.

je ne suis pas sûr de comprendre ce que vous entendez par « deuxième ligne écrite en JavaScript » ? transmettez-vous l'intégralité de l'instruction au compilateur ou non ?

je ne suis pas sûr de comprendre ce que vous entendez par « deuxième ligne écrite en JavaScript » ? transmettez-vous l'intégralité de l'instruction au compilateur ou non ?

Je ne veux pas modifier ce code car il doit être transmis au serveur Selenium tel quel.

Je ne veux pas modifier ce code car il doit être transmis tel quel au serveur Selenium.

s'il s'agit d'un fichier .ts, il sera transformé par le compilateur. Le compilateur supprime les annotations de type pour vous.

Quoi qu'il en soit, pour cet exemple, tout ce dont vous avez besoin est de declare var browser: any; et vous ne devriez pas obtenir d'erreurs. voir Aire de

s'il s'agit d'un fichier .ts, il sera transformé par le compilateur. Le compilateur supprime les annotations de type pour vous.

J'ai besoin d'une garantie qu'un code donné s'est exécuté sans altération dans IE6 et d'autres anciens navigateurs.
Par exemple, Node.js suit le système de modules CommonJS, mais mon require est une fonction personnalisée définie par d'autres développeurs sur ses pages. C'est pourquoi j'aimerais inclure ce code sans aucune post- et pré-modifications. C'est important pour moi et mon équipe.

Quoi qu'il en soit, pour cet exemple, tout ce dont vous avez besoin est de déclarer var browser : any; et vous ne devriez pas obtenir d'erreurs. voir Aire de jeux pour un exemple.

En fait, l'objet navigateur est l'objet le plus populaire de mon projet et il n'y a aucune raison de l'ignorer. La méthode browser.execute a également sa propre déclaration de type.

maintenant je ne suis pas sûr de comprendre quel est le problème alors. Quelle est l'erreur que vous obtenez?

Mon code est exécuté dans différents contextes : nœud et navigateur. Les problèmes actuels pour le second contexte sont les annotations de type et la modification de code.

img-2017-03-07-02-10-28

let { value } = browser.waitForPromise(() => { // node
    return browser.executeAsync( // node
            function (method, name, resolve) { // browser
        require(['patron.Locator/patron.Locator.Manager'], function (locator) {  // browser
            resolve(result);  // browser
        });  // browser
    }, method, name); 
});

Voici une implémentation simple de la méthode browser.executeAsync :

browser.executeAsync  = (...args) => {
   let script = args.shift();

   RPC.Selenium('/session/:sessionId/execute', {
         script: `return (${script}).apply(null, arguments)`, 
         args
    });
}

Comme vous le voyez, j'utilise TypeScript pour les tests d'intégration.

Quel est le message d'erreur?

Erreurs types :

TS2345: Argument of type 'string[]' is not assignable to parameter string
TS7006: Parameter 'error' implicitly has an 'any' type
TS7006: Parameter 'attach' implicitly has an 'any' type
TS7006: Parameter 'message' implicitly has an 'any' type
TS7006: Parameter 'model' implicitly has an 'any' type

Etc...

Définissez correctement require .

declare function require(v: string[]): any;

Définir correctement l'exigence.

Je ne peux pas. Dans mon cas, la méthode executeAsync contient du code pour des projets tiers et il existe différentes variantes pour de tels require s. Le code ci-dessus n'est qu'une fonction parmi des centaines.
Mon désir est très simple - permettez-moi d'exclure du code quand j'en ai besoin :)

vous pouvez mettre le declare function require(v: string[]): any; localement. par exemple:

// module a.ts
export var ...

declare function require(v: string[], callback: Function);

let { value } = browser.waitForPromise(() => { 
    return browser.executeAsync( 
        function (method, name, resolve) { // browser
            require(['patron.Locator/patron.Locator.Manager'], function (locator) {  // OK
                resolve(result);  
            });  
        }, method, name);
});

vous pouvez également simplement lancer sur any si nécessaire :

let { value } = browser.waitForPromise(() => { // node
    return browser.executeAsync( // node
        function (method, name, resolve) { // browser
            (<any>require)(['patron.Locator/patron.Locator.Manager'], function (locator) {  // browser
                resolve(result);  // browser
            });  // browser
        }, method, name);
});

Cela devrait produire un code identique.

Dans mon cas, j'ai une classe abstraite privée (non exportée) qui n'est censée être étendue que par deux classes :

abstract class IParent {
  static fromConfig(config: ParentConfig): IParent {
    // actual code is 20 lines long, not this simple
    // this throws "Cannot create an instance of the abstract class 'Parent'"
    return new this().applyConfiguration(config);
  }
  abstract method1(): void;
  ...
}

export class FirstChild extends IParent {
  specificMethodForFirstChild() { ... }
  method1() { ... }
  ...
}

export class SecondChild extends IParent {
  specificMethodForSecondChild();
  method1() { ... }
  ...
}

Usage:

let first = FirstChild.fromConfig({ ... });
let second = SecondChild.fromConfig({ ... });

// this runs successfully:
(first as FirstChild).specificMethodForFirstChild();
(second as SecondChild).specificMethodForSecondChild();

Mais sur la méthode fromConfig() j'obtiens "Impossible de créer une instance de la classe abstraite 'Parent' :

Code aire de jeux

  • Je peux dupliquer les méthodes statiques et leur faire appeler une fonction commune, mais cela semble assez stupide lorsque j'ai déjà un code fonctionnel.
  • Je ne peux pas rendre la classe non abstraite car les sous-classes appliquent l'implémentation de la méthode.
  • Je peux supprimer les méthodes abstraites mais je les utilise pour appliquer la même interface sur les sous-classes.
  • Je peux utiliser une interface séparée pour l'appliquer, mais la superclasse ne s'adaptera pas à l'interface et c'est le type renvoyé par la méthode statique.
  • Je n'ai pas l'intention d'appeler la méthode statique sur la classe abstraite, je veux juste qu'elle instancie une classe différente sur les différentes sous-classes

Le compilateur n'impose pas que les constructeurs de classes dérivées aient la même signature que la base. en d'autres termes, le constructeur de la classe dérivée peut avoir plus d'arguments requis que la base. l'utilisation de new this() suppose que tous les constructeurs dérivés n'auront pas de paramètres requis ; et c'est quelque chose qui n'est pas vérifiable.

Si vous êtes sûr que cela est correct, envisagez de lancer le casting comme new (<any>this)(x, y);

Bon point je n'avais pas vu ça. Votre suggestion fonctionne réellement, je vais considérer les dangers, merci.

Existe-t-il un moyen de faire taire le Module ... was resolved to ..., but '--allowJs' is not set ? dans mon cas d'utilisation, il existe un système de génération qui s'occupe de cela et je n'ai pas besoin de passer tout mon code via TSC, j'aimerais donc faire taire ces erreurs.

'déclarer le module "unModule" ;' dans l'un de vos fichiers .d.ts.

Ou installez le package @types correspondant s'il existe.

J'ai un autre exemple de quand cela serait utile:

const Button = (
  content: contentTypes,
  action: React.EventHandler<React.MouseEvent<HTMLDivElement>>,
  disabled: boolean
): JSX.Element => (
  <div className={`Button disabled-${disabled}`} onTouchStart='' onClick={ !disabled ? action : undefined } >
    { content }
    <div className='background'></div>
  </div>
);

Cela renvoie une erreur car onTouchStart n'accepte pas une chaîne comme paramètre qui est vrai. Cependant, onTouchStart='' corrige le comportement css cassé sur les appareils tactiles lié à certaines règles css. Je ne voudrais pas désactiver cette erreur globalement ou redéfinir certains types JSX. Je voudrais juste sur cette ligne pour supprimer cette erreur.

onTouchStart={<any>''}

Cela ne résout pas le problème en fait.
J'obtiens cette erreur :
error
C'est cassé sous la syntaxe tsx

onTouchStart={'' as any} , plutôt (oublié que JSX utilise une syntaxe d'assertion alternative)

@RyanCavanaugh le code généré serait-il considéré comme un cas d'utilisation légitime pour cette fonctionnalité ? J'utilise swagger codegen pour créer un client API pour un service de nœud. J'utilise également les types du client généré sur mon serveur, car il transforme les définitions de swagger en interfaces TypeScript, c'est donc le moyen le plus simple de m'assurer que je respecte mon propre contrat de swagger.

Le code généré est un peu bizarre cependant, et il a des blocs comme celui-ci :

let contentTypeHeader: Dictionary<string>;
if (contentTypeHeader) {
    fetchOptions.headers = contentTypeHeader;
}

Cela donne une erreur si strictNullChecks est activé, j'ai donc désactivé le drapeau pour l'ensemble du projet. Ce qui craint. Je ne veux pas analyser le script dactylographié généré et le modifier, mais je serais prêt à insérer quelque chose comme <tsc strictNullChecks=false /> en haut du fichier (similaire à la suggestion de

Ne s'agirait-il pas d'une demande de modification du générateur de code swagger pour produire un code conforme à strictNullChecks ?

@mhegazy bien sûr - mais ce n'est qu'un exemple de quelque chose comme ça. Il existe de nombreuses façons dont la génération de code est utile dans TypeScript (plus qu'en JavaScript). Donc, idéalement, il y aurait un moyen de ne pas forcer les gens à ramener leurs propres projets aux normes de leur code généré.

Mais ils le sont :) Le code que vous obtenez à partir de votre outil de génération automatique génère des types qui entrent dans votre compilation. si l'outil de génération de code ignore --strictNullChecks alors votre code observe des types non trompeurs.
désactiver les contrôles ne fait qu'étouffer l'alarme incendie. le problème n'est pas l'alarme, c'est ce qui cause l'incendie en premier lieu.

@mhegazy Je suis d'accord pour étouffer l'alarme incendie dans le code généré par un outil très bien testé. Le code est bon, ils n'utilisent tout simplement pas les fonctionnalités de langage de pointe, et ils ne devraient pas avoir à le faire.

Que diriez-vous d'un exemple moins controversé - et si le code généré a un local inutilisé ? Cela ne cause aucun dommage à mon code - sauf dans le cas où je dois désactiver noUnusedLocals dans tsconfig - ce que je fais maintenant.

Que diriez-vous d'un exemple moins controversé - et si le code généré a un local inutilisé ? Cela ne cause aucun dommage à mon code - sauf dans le cas où je dois désactiver noUnusedLocals dans tsconfig - ce que je fais maintenant.

si vous ne vous souciez pas du code généré, il devrait être au format .js avec un compagnon .d.ts. de cette façon, vous pouvez le vérifier, mais vous n'avez pas à le compiler.

le compilateur dactylographié ne semble pas aimer les mixins underscore.js utilisés avec la chaîne.

_.mixin(){sortFunciton : sortFunc(), otherChainFunc : otherFunction()}

....

unVal = _.chain(unTableau)
.sortFunction()
.otherChainFunc()
.valeur();

...

Un exemple assez simple est lorsque vous créez un écouteur pour le clic, par exemple avec @HostListener() pour Angular, comme ceci :

@HostListener('click', ['$event'])
onClick(event: MouseEvent) {
    // Code here...
}

Si j'active noUnusedLocals , j'ai l'erreur suivante :

ERROR in ./src (20,13): 'onClick' is declared but never used.

Est-ce que je peux laisser le compilateur ignorer cela ?

@JeremyCarlsten

_.mixin(){sortFunciton: sortFunc(), otherChainFunc: otherFunction()}

ressemble à un code invalide.

@leocaseiro Pourquoi doit-il être privé ? Dans ce cas, onClick est une méthode qu'angular finira par utiliser. Un problème similaire se produit toujours lorsque nous déclarons des variables privées que nous utilisons dans un modèle. Si vous les utilisez dans le modèle, rendez simplement les variables publiques. Cela a du sens puisque vous laissez angular les utiliser.

Salut @jmlopez-rod, tu as raison.

Intéressant qu'en tant que public, ça passe maintenant ! J'apprécie vraiment votre aide.

@leocaseiro public est le niveau de visibilité par défaut, vous n'avez donc pas besoin de le spécifier.

Des excuses à l'avance si cela semble négatif - j'ai peut-être raté quelque chose (nouveau pour TS).
Un autre exemple (j'utilise uniquement TS pour produire ES5 - pas de casting, de déclaration, d'interfaçage)

// do-as-i-tell-you-start
const factory = () => {
  const _this = [];
  let _value;
  Object.defineProperties(_this, {

    // Error: Property 'getset' does not exist on type 'any[]'.
    // true at at creation but not when used – don't MOM me!
    'method1': { value(){ return _this.getset; } },   

    // Works with property strings – I don't want this
    'method2': { value(){ return _this['getset']; } }, 

    'getset': { get(){ return _value; }, set(value){ _value = value } },
  });
  return _this;
}

vrai à la création mais pas lorsqu'il est utilisé - ne me MOM pas !

C'est précisément ce pour quoi TypeScript est conçu. Si vous ne souhaitez pas utiliser de types et de transtypage, pourquoi utilisez-vous TypeScript ? Comme indiqué à plusieurs reprises dans ce fil, il émettra toujours le code, vous ignorez donc déjà les erreurs à vos risques et périls. Pourquoi essayer de simplifier TypeScript, dans quel but ?

Pourquoi essayer de simplifier TypeScript, dans quel but ?

Il s'agit de déplacer une équipe de ES5 => ES6 (Babel ou TS) => TS dans toute sa splendeur - à petits pas.

Mon impression était que TS est un ajout à JS vous permettant d'intervenir à quel niveau vous êtes.
La raison de ma plainte est que l'exemple factice fourni génère une erreur et donc _does
pas produire ES5_. Il ne devrait pas être obligatoire de transpiler le linting de l'OMI.

À moins que vous n'ayez pas d'émission en cas d'erreur, elle émettra. Il produit donc ES5.

Ça n'a pas marché - je suis passé à Babel - ça a marché

tsc peut être configuré pour émettre la sortie indépendamment des erreurs de type, regardez l'option noEmitOnError .

Si vous utilisez ts-loader, il dispose également d'une nouvelle option transpileOnly où il sera simplement transpilé et n'affichera aucune erreur.

@trusktr merci - je vais essayer :-)

les erreurs ne bloquent pas la génération des sorties, ni l'outillage

Ce n'est pas vrai. Nous avons une configuration (assez courante - elle vient du démarreur) dans le pack Web qui, en production, plante et ne produit rien. Et il devrait en être ainsi - le compilateur signale des erreurs, le programmeur revient et les corrige. Pourquoi utiliser des types lorsque toute l'équipe les ignore parce que la compilation "fonctionne" ? De même, si tsc ne parvient pas à compiler, l'actualisation automatique ne fonctionne pas (le plugin est intentionnellement écrit de cette façon - il ne s'actualise pas si votre code est erroné [ou considéré comme erroné par le compilateur]).

La suppression des erreurs est utile lorsqu'il y a un bogue dans tsc. Par exemple, cela devrait compiler :

interface A {
  isEmpty(x: any[] | string | object): boolean;
}

const a: A = <A>{};
a.isEmpty({a: 1});

mais dans la version actuelle de TS, il échoue.

Edit : appel de fonction fixe (mauvaise ligne copiée)

Par

a.isEmptyObject({a : 1});

tu veux dire

a.isVide({a : 1});

?

Oh oui. Mauvaise ligne copiée :/.

La suppression des erreurs est utile lorsqu'il y a un bogue dans tsc.

Un bug empêchant l'émission devrait être corrigé. Il est très peu probable que la possibilité d'ignorer une erreur fasse que tsc émette soudainement quelque chose lorsqu'il a un bogue qui le fait planter.

J'ai un import qui ressemble à ça :

import * as reducers from "./**/reducer.ts"

J'utilise d'abord TypeScript, puis Babel. J'ai un plugin babel qui traite * dans les importations comme un modèle glob. TypeScript renvoie une erreur se plaignant de .ts , puis si .ts est supprimé, il ne peut pas trouver le module.

Je ne sais pas vraiment comment résoudre ce problème, mais ma première pensée a été de supprimer les erreurs liées à cette ligne. J'ai essayé de mapper les modules dans la configuration, mais * est également traité comme un caractère générique et ne peut pas être échappé.

@lukescott dans un .d.ts dans le cadre du compilateur :

declare module './**/reducer' {
  export = {
    [reducer: string]: () => void; /* or whatever */
  };
}

Un autre exemple de la façon dont cela serait utile:

const req = https.request({
        host: 'www.google.com',
        method:'GET',
        path:'/',
        port: 443,
}, (res) => { 
    console.log(res.connection.getPeerCertificate());
});

Le getPeerCertificate indique qu'il n'existe pas en raison de définitions erronées dans le nœud https ( également celui-ci ).

Il compile et fonctionne toujours avec le gros soulignement rouge, mais ce serait très bien de le faire

console.log(res.connection.getPeerCertificate()); //ts:disable-line

@trusktr
Oups, on dirait que j'ai gâché la syntaxe en la convertissant à partir du code prod. Voici un aperçu de ce que j'essayais de décrire. Peut-être plus d'un problème avec les définitions de soulignement. Mais si une bibliothèque tierce cause des problèmes avec le compilateur ts, ne devrions-nous pas pouvoir ignorer cette ligne de code ?

+1. Cela sera utile pour les tests, car je dois m'assurer que mon code renvoie une erreur lorsqu'il est passé dans quelque chose auquel il n'attend pas.

Cette fonctionnalité utile serait simplement la généralisation de ! pour des objets éventuellement nuls.

Si je veux apporter un fichier de bibliothèque dans un projet (par exemple Chartjs), je l'enregistre souvent en tant que fichier TS (j'aime conserver tous les fichiers source en tant que TS et compilés en tant que JS) et l'importer avec une référence à triple barre oblique dans le TS fichier qui le requiert. Cependant, le TypeScript se plaint ensuite sans cesse des erreurs dans ce fichier (naturellement, car il s'agit simplement d'un fichier JS standard enregistré en tant que TS).

Cependant, la possibilité d'ajouter :

/*ts-errors-disable*/ au début du fichier de bibliothèque et /*ts-errors-enable*/ à la fin réduiraient la sortie d'erreurs qui ne sont pas pertinentes mais permettraient toujours aux développeurs de conserver tous les fichiers source en tant que TS.

Ou devrais-je simplement faire les choses fondamentalement différemment ?

@benfrain Eh bien, il serait préférable d'installer le fichier de définitions TypeScript correspondant s'il existe ( npm install --save-dev @types/mylibrary ) ou de créer votre propre fichier _.d.ts_ avec un type any dans l'espace de noms de votre bibliothèque /classe principale en premier :

// mylibrary.d.ts
declare module "mylibrary" {
    let mylibrary: any;
    export = mylibrary;
}
// main.ts
import mylibrary = require("mylibrary");
...

J'ai une question. D'abord le code et l'erreur que TypeScript met en évidence :

import {Directive, ElementRef, Input, OnChanges, SimpleChange} from '@angular/core'

@Directive({
  selector: '[blankAttr]',
})
export class BlankAttr implements OnChanges {
  @Input('blankAttr') private attrName: string // <--- TS Error: unused variable

  constructor(private el: ElementRef) {}

  public ngOnChanges(changes: {[key: string]: SimpleChange}): void {
    const change: any = changes.attrName 
    const prevValue: any = change.previousValue

    if (prevValue) {
      this.el.nativeElement.removeAttribute(prevValue)
    }
    this.el.nativeElement.setAttribute(change.currentValue, '')
  }
}

Le problème que j'ai est que je dois déclarer le décorateur @Input pour permettre à l'attribut de passer une chaîne. Mais je ne me soucie que de la valeur de cette chaîne lorsqu'elle change. Et je peux obtenir la valeur précédente et actuelle lors de la gestion de l'événement de modification.

Pouvons-nous avoir un // ts-ignore maintenant ? Ou existe-t-il un autre moyen de résoudre ce problème ?

@uglow pourquoi attrName privé ? Il s'agit d'une variable qu'Angular modifie afin que vous puissiez obtenir une valeur avec elle. Il doit donc être public.

@jmlopez-rod Je l'ai changé en public, mais cela ne change pas le problème. TS dit que c'est une variable inutilisée.

J'utilise TS 2.4.1, après l'avoir rendu public, le texte dactylographié cesse d'émettre l'erreur.

Avant:
screen shot 2017-07-26 at 9 53 13 am

Après:
screen shot 2017-07-26 at 9 53 39 am

J'utilise 2.3.3. Je vais essayer la 2.4.1. Merci

Cela devrait être inclus. Je travaille avec un moteur js personnalisé qui permet à un seul fichier .js de renvoyer une valeur. Voir mon essence pour un exemple . J'utilise TS pour générer mes fichiers .js et bien sûr, TS ne le sait pas et lance :

A 'return' statement can only be used within a function body.

@mhegazy J'ai rencontré ce genre de problème de différentes manières.

Ma situation actuelle (l'ensemble du flux suppose le mode déclaration) :

  • les décorateurs de classe nécessitent une déclaration de classe (pas une expression de classe) et je suis dans une fonction - en principe, cela pourrait être corrigé, mais ce n'est pas le cas aujourd'hui.
  • ok, pas de problème je vais faire de l'expression une déclaration
  • pas de dé, la déclaration a maintenant un nom inutilisé
  • ok pas de probleme je le retourne
  • pas de dés, Return type of public method from exported class has or is using private name
  • ... ?

Fondamentalement, la cause première ici est que les expressions ne peuvent pas être décorées, mais il est déraisonnable pour vous de tout supprimer pour implémenter cette fonctionnalité. En attendant, il est judicieux pour moi de simplement supprimer cette erreur. Je serais bien si la suppression d'une erreur m'obligeait à trouver le problème TypeScript associé et à dire quelque chose comme // TS-LIMITATION:#9448 bien que je soupçonne que cela entraînerait une énorme quantité de nouveaux problèmes inutiles de votre point de vue.

Je serais même bien si vous ajoutiez des suppressions ciblées spécifiques pour des problèmes connus que vous n'êtes pas encore prêt à aborder, mais seulement si cela était fait rapidement et sans trop d'effort de conception (cela rendrait le mécanisme inutile :wink: )

Je ne veux pas obtenir d'erreur de code inaccessible (où je suis heureux d'annoter "fermez-vous sur l'erreur de code inaccessible ici") quand je fais quelque chose comme
if (false){ ...complicated debug code that I dont want to delete/forget... }

Ainsi, il manque toujours au compilateur TypeScript une option pour "se taire et ne pas gâcher d'autres outils". Il serait vraiment utile pour nous d'avoir cette option via les commentaires et via les commutateurs du compilateur pour des fichiers spécifiques ou même glob. Nous sommes bloqués sur l'utilisation de l'ancienne version des outils car nous ne voulons pas perdre le rechargement automatique (les versions plus récentes ne se rechargent pas automatiquement en cas d'erreur). Donc, nous désactivons l'option boguée noImplicitAny (ce que je ne veux vraiment pas, j'utilise TypeScript à cause de la vérification de type et avec le droit implicite, tout TypeScript n'apporte pas grand-chose à une table) ou restons sur les anciennes versions des packages. Oui, j'ai signalé le bogue dans les deux chargeurs WebPack et AwesomeTypeScript , mais personne ne s'en soucie. La question est ignorée depuis plusieurs mois maintenant. Je vois que c'est exactement la même chose avec le package TypeScript :-(.

@polyglotinc if (!!false) {

@RyanCavanaugh Eh bien, d'ailleurs, (!true) fonctionne ... Je n'y ai même pas pensé comme des possibilités parce que j'_(en tant qu'ex-compilateur-écrivain)_ a donné plus de crédit au compilateur en ce qui concerne la constante / le littéral expression s'effondrer... Je suppose que j'ai pensé que si ça allait être un corps occupé à propos de if (false) , il saurait que if (!true) était la même chose !

@unional la question SO pourrait être écrite un peu plus clairement et c'est peut-être pourquoi nous avons besoin du compilateur pour nous informer des erreurs possibles. Voir cette capture d'écran montrant l'erreur que l'utilisateur souhaite supprimer

screen shot 2017-08-09 at 12 43 20 am

Notez que dans la capture d'écran, je n'ai qu'une seule erreur. C'est parce que j'ai déjà corrigé un problème détecté par le compilateur.

private keyHandlers = {
    'ArrowDown': function ($event: any) {
      this.handleArrowDown($event);
    },
    'ArrowUp': ($event: any) => {
      this.handleArrowUp($event);
    },
  };

L'utilisateur prétend que le handleArrow* est utilisé mais le script dactylographié ne le voit pas être utilisé. En ce qui concerne le texte dactylographié, le this dans this.handleArrowDown($event); pourrait être n'importe quel objet qui a la méthode handleArrowDown . Avec la fonction flèche, il sait maintenant que this est l'instance de la classe et donc il voit que handleArrowUp est utilisé.

Autre option : utilisez le faux premier paramètre this .

  private keyHandlers = {
    'ArrowDown': function (this: SomeComponent, $event: any) {
      this.handleArrowDown($event);
    },
    'ArrowUp': ($event: any) => {
      this.handleArrowUp($event);
    },
  };

@jmlopez-rod Merci. Ce sont de bonnes alternatives. J'aime particulièrement la solution function(this: SomeComponent, ...) {...} car c'est la plus flexible.

La fonction flèche ne fonctionne pas si le keyHandlers ne fait pas partie de la classe :

const keyHandlers = {
  'ArrowDown': function (this: SomeComponent, $event) {
    this.handleArrowDown($event); // error on accessing private method, filing an issue for it.
  },

  'ArrowUp': ($event) => { // doesn't work, duh
    this.handleArrowUp($event);
  }
}

export class SomeComponent {
  onKeyDown($event) {
    if (typeof keyHandlers[$event.code] === 'function') {
      keyHandlers[$event.code]($event);
    }
  }
  private handleArrowDown(_event) {
    // ...
  }

  private handleArrowUp(_event) {
    // ...
  }
}

D'autre part, la fonction flèche est la plus simple dans ce contexte.

J'essaie de définir manuellement window.console pour IE9 afin d'éviter les erreurs lors de l'utilisation de console.log :

if (!window.console)
    window.console = {};

Mais je reçois error TS2540: Cannot assign to 'console' because it is a constant or a read-only property. Existe-t-il une solution de contournement pour ces cas d'utilisation ?

@amiraliakbari Vous pouvez affirmer window tant que type any , ce qui vous permet effectivement de désactiver les vérifications de type :

(window as any).console = {};

cela a fonctionné pour moi pour remplacer/désactiver console.log globalement -- Notez que Project.logging été défini avant cela

(window.console as any).___real_log = window.console.log;
window.console.log = function(args) {
  if (Project.logging) return (window.console as any).___real_log(args);
  return;
};

C'était aussi beaucoup plus propre que de mettre des instructions if partout dans mon code car je peux simplement utiliser console.log comme d'habitude

Comme mentionné dans #19109, nous n'avons toujours pas la possibilité de supprimer une erreur spécifique .

Comme mentionné dans #19109, nous n'avons toujours pas la possibilité de supprimer une erreur spécifique.

Je pense que le scénario de base décrit dans ce numéro a été abordé. nous pouvons créer un nouveau problème pour suivre la suppression globale des erreurs à l'aide du numéro d'erreur. Nous avons été réticents à utiliser des codes d'erreur de cette manière parce qu'ils manquent d'expressivité.

Créé #19139.

Cette instruction ne fonctionne que par fichier, non ? Est-il possible de le faire fonctionner sur dossier ?

L'instruction est censée fonctionner pour une seule ligne à la fois. Si vous voyez beaucoup d'erreurs de compilateur dans votre projet, vous pouvez vérifier que vous devriez avoir des options de compilateur moins strictes, comme laisser noImplicitAny désactivé (c'est-à-dire que les variables sont implicitement any sinon annoté). Vous pouvez également laisser certains fichiers en JS et activer allowJs mais checkJs désactivés.

Pourquoi avez-vous fermé ce problème ? La solution manque encore ! Pourquoi avez-vous des discussions insignifiantes pendant 2 ans au lieu d'intégrer une véritable possibilité de suppression d'erreurs ?

@webia1 Vous pourriez être intéressé par le #19139 qui est toujours ouvert.

(Ajouter ce commentaire ici car il pourrait être utile pour ceux qui tombent sur ce problème, comme je l'ai fait)

J'ai parcouru https://github.com/Microsoft/TypeScript/pull/21602 et cela pourrait être la solution.

Ajoutez simplement // @ts-ignore à votre code (ou même // @ts-ignore <some code error> pour ignorer uniquement l'erreur spécifiée) .

Testé ici avec TypeScript 2.7.2 et ça marche !

(ou même // @ts-ignorepour ignorer uniquement l'erreur spécifiée).

21602 n'a pas été fusionné. Vous ne pouvez pas ignorer seulement certaines erreurs.

@RyanCavanaugh tu as raison ! J'ai mis à jour mon commentaire. Merci!

Arrivé ici en cherchant à supprimer l'erreur TS2339.

document.getElementById('theme-admin').disabled = false; /* tslint:disable */
document.getElementById('theme-member').disabled = true; /* tslint:disable */
Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

Roam-Cooper picture Roam-Cooper  ·  3Commentaires

weswigham picture weswigham  ·  3Commentaires

manekinekko picture manekinekko  ·  3Commentaires

MartynasZilinskas picture MartynasZilinskas  ·  3Commentaires

jbondc picture jbondc  ·  3Commentaires