Typescript: Möglichkeit, TS zu überlasten und spezifische Fehler des Entwicklers zu ignorieren

Erstellt am 30. Juni 2016  ·  150Kommentare  ·  Quelle: microsoft/TypeScript

Ein Entwickler sollte in der Lage sein, einen Kommentar über einem ts-Fehler hinzuzufügen, wie z

/// TS_IGNORE
let a:string = 1

und lassen Sie den Compiler diesen Fehler nicht melden ...
Es gibt bestimmte Szenarien, die der Entwickler am besten kennt und die Fehlermeldungen zum Schweigen bringen möchte.

irgendwie wie :irgendwie

Grüße

Sean

Fixed Suggestion

Hilfreichster Kommentar

Einfach besetzen (Besetzung ist kein offizieller Begriff, aber das gleiche Konzept)

const foo: string = 7 as any;

Suchen Sie das?

Alle 150 Kommentare

Einverstanden. Sehnsucht nach so etwas wie Java @SuppressWarnings , insbesondere für den Fall beschrieben , hier :

Folgende:

const typeMetadataKey = Symbol('type');

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

Erzeugt den Fehler: Unable to resolve signature of class decorator when called as an expression. .

Bei Verwendung wie folgt:

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

Der Decorator funktioniert wie erwartet und wird kompiliert, gibt aber den obigen Fehler aus.

Wenn Sie darüber nachdenken, wie dies gelöst werden könnte, gehen Sie gerne darauf ein, wenn jemand in die richtige Richtung weisen möchte.

Einfach besetzen (Besetzung ist kein offizieller Begriff, aber das gleiche Konzept)

const foo: string = 7 as any;

Suchen Sie das?

Ich habe nur ein Beispiel gegeben, nicht wirklich ein Fall (ich weiß alles über Casting), ich habe andere Fälle wie
Super wird nach der ersten Zeile des Konstruktors und anderen Problemen aufgerufen ...

  • wird den Übergang zu TS von JS + erleichtern, wenn Sie eine Lib ändern und Tonnen von Fehlern erhalten und Sie nur die Dinge bereinigen möchten, wie Sie als Entwickler aus dem Grund wissen ...

das ist ein wichtiges Feature

Also so etwas wie // tslint:disable ?
Möglicherweise können Sie sogar bestimmte Prüfungen tsc ausschalten, die
_zB:_ const FooBar: string = 'rozzzly'; // tslint:disable-line camelcase

das wäre super...

Ich weiß es nicht... Ich denke, das liegt außerhalb des Rahmens von tsc . Dafür sind Linters da.

da muss man "die Klappe halten" können :)

Ich denke, es gibt Argumente für die Unterdrückung von Fehlern / Warnungen bei "experimentellen" Funktionen wie Dekoratoren, bei denen die API etwas flüchtig ist und die Fehler möglicherweise nicht immer genau sind. Sie erhalten eine (sehr spezifische) Version davon, indem Sie einfach das tsconfig-Feld "experimentalDecorators" verwenden, aber es unterdrückt nur eine Art von Warnung.

Um meinen eigenen Devil's Advokat zu spielen, könnte dies neue Benutzer von TypeScript ermutigen, Warnungen zu unterdrücken, die sie nicht verstehen, anstatt zu erfahren, warum die Warnung auftritt. Und bei experimentellen Funktionen ist jeder ein neuer Benutzer - die Möglichkeit, Fehler zu unterdrücken, könnte Benutzer mit Fehlern in neuen Funktionen selbstgefällig machen, anstatt Probleme zu öffnen.

Letztendlich möchte ich immer noch, dass meine Syntastic-Ausgabe sauber ist. Das bedeutet, den Fehler zu unterdrücken. Das wäre natürlich _nach_ Ich öffne das Thema für einen möglichen Fehler und versuche mehr zu erfahren. ;)

Das Problem beim "Shutdown it up" ist, dass Sie nicht wissen, was Sie aus "item" herausholen. Also ist let a:string = 1 ein number oder ein string ? Was ist, wenn es eine weitere Deklaration von a , wird sie zusammengeführt oder nicht? Was wäre, wenn jemand den Typ dieser Variablen erfasst hätte, zB return {a} ; , sollten sie { a : number } oder { a: string } oder beiden zuweisbar sein.

Eine grundlegende Sache, Fehler sind alle unwürdig. Fehler blockieren weder die Generierung von Ausgaben noch die Werkzeugausstattung.

Es gibt verschiedene Mechanismen, die es Ihnen ermöglichen, die Überprüfung bestimmter Teile Ihres Codes zu unterdrücken, zB any , Typzusicherungen (Umwandlungen) und Ambient-Deklarationen.

Wenn Sie beispielsweise eine Bibliothek mit einer "ungültigen" Definition haben, können Sie sie einfach entfernen und durch declare module "blah" { export = any } ersetzen. oder declare var $: any und schon kann es losgehen.

Da ich normalerweise auf diese Anfragen antworte, denke ich, dass Ihr Problem nicht darin besteht, den Fehler zu unterdrücken. Das eigentliche Problem ist, dass Sie einen Fehler erhalten, den Sie nicht nützlich finden. unterdrücken, dass das zugrunde liegende Problem nicht löst, sondern es nur abdeckt und Auswirkungen eines inkonsistenten Zustands ohne Vorwarnung hat. Die richtige Lösung besteht darin, zu wissen, was der Fehler ist, den Sie erhalten? um welche bibliothek handelt es sich? und warum der Compiler einen unbrauchbaren Fehler ausgibt...

Und dafür müssen wir mehr über Ihren Anwendungsfall wissen.

Wir haben in TS 2.0 einige Arbeit geleistet, um einige dieser zugrunde liegenden Probleme zu lösen, zum Beispiel;

nimm einfach irgendeinen, so ist "sei still", die Vorzüge davon (oder eigentlich das Fehlen davon) ist eine andere Frage

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

ok, aber auch hier liegt das Problem nicht speziell beim Casting

<any> gibt Ihnen Vanila-Javascript mit 100% Freiheit von allen lästigen Dingen von TypeScript, was brauchen Sie also noch?

In meinem Fall rufe ich super nicht als erste Zeile des Konstruktors auf und muss den Fehler beruhigen

Anstatt zu versuchen, es zu zwingen, ein Antimuster zu akzeptieren, schreiben Sie etwas wie folgt:

_ 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');
    }
}

Das macht Typoskript so toll, _und auch nervig_. Es zwingt Sie, besseren Code zu schreiben, und macht Sie zu einem besseren Entwickler. Ein Projekt zu konvertieren macht keinen Spaß ; Sie könnten es als "Initiation" eines Entwicklers oder als "Feuerversuch" betrachten. :lachen: Aber man lernt viel, und es lohnt sich imho.

In meinem Fall rufe ich super nicht als erste Zeile des Konstruktors auf und muss den Fehler beruhigen

Und machen Sie Ihren Code inkompatibel mit ES6... Genau aus diesem Grund besteht der Hauptzweck von TypeScript darin, Ihnen 👣 :gun: aus der Hand zu nehmen.

Wenn TypeScript etwas nicht richtig interpretiert, dann sollte es behoben und nicht "umgangen" werden. Nun gibt es ein paar Dinge, bei denen sich TypeScript eher wie ein Linter verhält und es noch kein Konzept von "Fehler" versus "Warnung" gibt. Ich kann unterdrückende Warnungen sehen, wenn sie kommen. Dinge wie Code nach Rückgabe und nicht verwendete Parameter sollten meiner Meinung nach Warnungen sein, da sie syntaktisch korrekt (wenn auch dumm) sind.

Hier ist ein weiterer Fall, in dem ich diese Funktion gerne hätte:

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;
  }
}

Im Moment gibt es einen Fehler von ts:

[ts] Klasse 'Hund' implementiert fälschlicherweise die Schnittstelle 'Animal'
Eigenschaft 'numberOfLegs' fehlt im Typ 'Hund'

Wie Sie sehen, ist der Compiler völlig falsch, aber ich möchte (und sollte nicht gezwungen werden) alle Eigenschaften der Schnittstelle nur um des Compilers willen kopieren.

@DethAriel Im Grunde fragen Sie nach einer Möglichkeit, Nebenwirkungen nach der Bedingung im Typsystem auszudrücken. Das ist interessant, aber ich habe das Gefühl, dass es zu einem schrecklich verworrenen Code führen würde.

@aluanhaddad Yup , das

Verwenden Sie einfach eine Kombination aus Schnittstelle und Klasse

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;
  }
}

Thx, @mhegazy , das hat tatsächlich funktioniert

Was ist, wenn der Fehler nicht <any> behoben werden kann?

Ich verwende die experimentelle Bind-Syntax wie hier besprochen https://github.com/Microsoft/TypeScript/issues/3508 und abgesehen davon, dass ich sie nicht verwende, kann ich den Compiler sonst nicht dazu bringen, den Fehler in jeder Zeile vor jedem :: zu ignorieren TS1128: Declaration or statement expected )

Ich verwende die experimentelle Bind-Syntax

das ist wirklich mehr, als nur eine Warnung abzulehnen. Der Parser unterstützt es nicht, daher ist der resultierende Baum völlig falsch, alle Compiler-Funktionen werden von diesem Punkt an nicht funktionieren, also keine Typrückschlüsse, keine Kompatibilitätsprüfungen, keine Formatierung, keine Vervollständigung, nichts. Daher ist es besser, alle Fehler zu ignorieren oder einfach in einer .js-Datei zu arbeiten.

Ich konvertiere derzeit ein riesiges JS-Projekt in Typoskript und nachdem ich die Konvertierung durchgeführt habe, wenn ich den Befehl gulp build ausführe, sehe ich während der Kompilierung ungefähr 2000 TS-Fehler und die meisten Fehler beziehen sich auf eine Eigenschaft, die für eine Klasse nicht definiert ist oder ein Modul nicht definiert. Ich denke, es muss eine Möglichkeit geben, diese Art von Fehlern zu unterdrücken, wenn die Ausgabe-JS-Dateien generiert werden.

Dies ist auch genau mein Fall, ich konvertiere eine App, die mit Modulen-als-Eigenschaften-Design vor ES6 erstellt wurde, also habe ich ein RIESIGE app.namespace1.namespace2.something.views.view -ähnliches globales Objekt.

Ich schreibe einen Teil davon um und verlasse mich in meinem Code auf das globale app.*-Objekt und seine verschiedenen Unterelemente. Alles, was ich erhalte, ist eine Menge von Warnungen "Namespace 'App' kann nicht gefunden werden".

Ich habe alle meine globalen Abhängigkeiten in eine globalProxy.ts umgestaltet, daher erhalte ich die Warnungen nur hier, aber es wäre FANTASTISCH, am Anfang dieser Datei ein //TS-NO-WARNINGS hinzuzufügen, um die Konsole zu bereinigen von den offensichtlichen Botschaften...

TS-Fehler blockieren die Codegenerierung nicht. Sie können sie ignorieren, aber diese sagen Ihnen, dass der Compiler die Korrektheit Ihres Codes nicht bestätigen kann.

@zeeshanjan82 warum nicht --allowJs und Datei für Datei migrieren? Mit diesem Setup erhalten Sie keine Typfehler von JavaScript-Quellen. Sie können auch eine Ambient-Platzhalterdeklaration verwenden, um Fehler bei der Modulauflösung zu unterdrücken, wie z
_globals.d.ts_

declare module '*';

Hier ist ein weiterer Anwendungsfall für die Fehlerunterdrückung.

Die Betreuer der Momentbibliothek haben vergessen, isoWeek als gültigen String zur Parameteraufzählung für die Methoden startOf und endOf hinzuzufügen. Es wurde in einer späteren Version behoben, aber dabei wurde die Art und Weise, wie diese Einheiten behandelt werden, vollständig überarbeitet, was zu viel Nacharbeit auf unserer Seite bedeuten würde.

Also haben wir die Version des Moments korrigiert, aber jetzt können wir isoWeek aufgrund von TS-Wurffehlern im Wesentlichen nicht verwenden. Ich stecke im Moment also zwischen einem Felsen und einem harten Ort fest.

Sie könnten einfach eine lokale Kopie hinzufügen. Sag etwas so Einfaches wie:

// ./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
        }
    }
}

jetzt prüft der Compiler Ihre lokale Kopie von override/moment.d.ts anstelle der mit dem Paket gelieferten. Dies kann natürlich eine lokale Kopie der Momentdeklarationsdatei oder eine kleine Menge von Dingen sein, die Sie benötigen.

Mir fehlt sowohl die Zeit als auch die Lust, meine eigenen Typisierungsdefinitionen für Bibliotheken von Drittanbietern zu pflegen ;)

Mir fehlt sowohl die Zeit als auch die Lust, meine eigenen Typisierungsdefinitionen für Bibliotheken von Drittanbietern zu pflegen ;)

Und das ist vollkommen in Ordnung. Verwenden Sie einfach declare module "moment"; was declare var $: any für Module entspricht, und der Compiler wird Sie nicht mehr damit belästigen.

Der Vorschlag von

Der Nachteil Zugabe von declare module "moment"; ist , dass Sie nicht mehr jede IDE IntelliSense oder statische Typprüfung für jeden Moment bezogenen Code haben. Und die auftretenden any s neigen dazu, in den umgebenden Code auszubluten und dort auch viele statische Prüfungen zu beenden. Das Unterdrücken von Fehlern im Zusammenhang mit einem einzelnen problematischen Enumerationswert ist ein hoher Preis.

@aluanhaddad Es war eine Pull-Anfrage geöffnet, um das Problem zu beheben, aber sie wurde zugunsten einer anderen geschlossen, die Breaking Changes einführte (und immer noch keine Unterstützung für isoWeek hinzufügte), also bin ich mir nicht sicher, was dort passiert ist .

Der Punkt ist, dass diese Probleme in Zukunft mit der Einführung von Angular 2 usw. häufiger auftreten werden, so dass eine Möglichkeit zur Unterdrückung bestimmter Fehler nützlich wäre, kann ich mir vorstellen.

Ich habe dieses Problem mit einer Knotenkernbibliothek (net, node 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; }'.'

Und auch mit ioredis-Bibliothek:

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

Wie @yortus und @adamreisnz darauf hingewiesen haben, ist dies ein häufiges Problem, da Definitionsdateien nicht immer korrekt aktualisiert werden. Außerdem, wenn Sie TS-Vorteile mit declare module "x"; opfern müssen, warum sollten Sie TS überhaupt verwenden?

Sie können das Modul auch um die fehlenden Typen erweitern, um die Intelligenz nicht zu verlieren.

Nun, wenn ich schreibe:

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

Der Typoskript-Compiler meldet immer einen Fehler Cannot find name 'Symbol' wenn target es5 , obwohl dieser Code tatsächlich so gut funktioniert, wie ich es erwartet habe.

Ich stimme also zu, dass wir dringend einige Kontrollanweisungen brauchen, die in Kommentarzeilen funktionieren.

declare var Symbol: any;

@gdh1995 @mhegazy Oder verwenden Sie einfach den echten Fix, der das lib Flag auf es2015 .

@mhegazy Danke. Ich finde das funktioniert gut:

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

@DanielRosenwasser Obwohl es2015 diese nützlichen Funktionen hinzufügt, ist mein Projekt darauf beschränkt, mit es5 kompatibel zu sein und dann sollte Symbol in anderen Dateien vermieden werden.

Was ich jetzt nicht verstehe ist, dass der TypeScript-Compiler mir Fehler gibt, selbst wenn ich typeof Symbol === "function" . Irgendein Rat?

Ein Fall, den ich gerne hätte, ist das Verspotten von Abhängigkeiten:

// 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;

Dieser Code hat den gewünschten Effekt, dass die Abhängigkeit innerhalb der getesteten Komponente verspottet wird, aber TypeScript wirft eine offensichtliche "Kann 'Abhängigkeit' nicht zuweisen, weil es keine Variable ist" aus. Error.

Ich bin mir sicher, dass die Antwort sein wird, dass ich den falschen Baum anbelle und so etwas wie inject-loader aber meiner Erfahrung nach sind diese Lösungen A) mühsam, um zu arbeiten / nicht immer Arbeit und B) sind nicht so einfach wie oben. Wie OP erwähnt, weiß der Entwickler manchmal am besten. Ich weiß, dass dies eine hackige Lösung ist, aber es funktioniert und ich würde es lieben, dass TS in diesem Fall einfach die Klappe hält.

Dieser Code hat den gewünschten Effekt, dass die Abhängigkeit innerhalb der getesteten Komponente verspottet wird, aber TypeScript wirft eine offensichtliche "Kann 'Abhängigkeit' nicht zuweisen, weil es keine Variable ist" aus. Error.

Dies ist ein Fehler in ES6. Wenn also in der Zukunft Engines ES6-Module nativ unterstützen, müssen Ihre Tests neu geschrieben werden.

Alternativ können Sie Ihr ComponentToTest ein Argument für Dependency ComponentToTest akzeptieren lassen, und Ihre Tests können das bestehen, oder einen Test-Hook haben, mit dem Sie den Wert von Dependency überschreiben können, bevor Sie Methoden aufrufen auf ComponentToTest .

Dies ist ein Fehler in ES6. Wenn also in der Zukunft Engines ES6-Module nativ unterstützen, müssen Ihre Tests neu geschrieben werden.

Ah fair genug, ich werde es dann fallen lassen, da diese Anforderung tangential zu diesem Thema ist.

Alternativ können Sie Ihr ComponentToTest ein Argument für die Abhängigkeit akzeptieren lassen, und Ihre Tests können dies bestehen ...

Ich denke, das ist es, was wir letztendlich gemacht haben. Es ist einfach ziemlich lahm, die API für eine Klasse neu definieren zu müssen, um sie testbar zu machen, aber ich denke, das ist überhaupt kein Problem, das nur für TS gilt.

Danke für das Feedback, @mhegazy

Ich möchte die Prüfung des Argumenttyps einer Funktion überschreiben.

Mein Anwendungsfall ist ziemlich einfach, ich habe eine Funktion wie diese:

function isValidId(s: string): boolean {}

die prüfen, ob ein String einer Regel folgt.
Es wird sowohl intern als auch zur Validierung von Benutzereingaben verwendet. Ich würde gerne Tests schreiben, um zu sehen, ob es false zurückgibt, wenn der Benutzer etwas einfügt, das kein String ist.

Streng genommen kann die Funktion alles als Eingabe akzeptieren, weil sie es verwalten kann, aber da wir sie auch intern verwenden, möchte ich angeben, dass wir einen String wollen

Daher hätte ich gerne etwas, um den Fehler über falsches Format in den Tests zu unterdrücken

@rpadovani verwende einfach any :

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

Das könnte ich auch gebrauchen. Wir haben eine Situation, in der foo(bar: any, baz: any) als Teil eines Frameworks definiert ist, aber in einigen Implementierungen von foo wird bar nicht verwendet. Bei aktivierter Typoskript-Fehlerprüfung wird ein Fehler ausgegeben, da eine nicht verwendete Variable deklariert wird. Es muss erklärt werden , da andere Versionen von foo, bar verwendet wird.

@benjaminabbitt Es scheint, dass foo (_bar: any, baz: any) für Sie funktioniert: Ein Name, der mit "_" beginnt, muss nicht verwendet werden.

Hinzufügen: Ich glaube, dass die Möglichkeit, spezielle Fehler zu überschreiben/zu ignorieren, wichtig ist.

Eine Herausforderung hierbei ist, dass immer wieder Leute auftauchen, die sagen, dass sie Fehler unterdrücken wollen, Code-Schnipsel posten und effektive Lösungen im Code finden, um diese Fehler zum Schweigen zu bringen (oder herauszufinden, dass ihr Code wirklich ein Problem hat). Es ist schwierig, diese Funktion zu entwickeln, ohne zu wissen, wie ein wirklich problematischer Fehler aussieht oder zu verstehen, welche Fehler die Leute global unterdrücken möchten.

Wie gehen wir am besten mit Javascript-Code von Drittanbietern um, den wir in unsere Projekte einbinden möchten?

Betrachten Sie das folgende Szenario. Es gibt eine riesige Bibliothek, die noch nicht in npm veröffentlicht wurde, und selbst wenn, würde die Verwendung der Bibliothek so, wie sie ist, dazu führen, dass unsere Anwendung viel toten Code mit sich herumträgt (Baumzittern kann nicht helfen, da sie alles an ein Objekt anhängen).

Nehmen wir an, es lohnt sich in diesem Fall einfach nicht, diesen Code zu extrahieren und in npm zu veröffentlichen. Welche anderen Möglichkeiten haben wir?

Bei meinem Versuch, diese Bibliothek zu verwenden, habe ich den Code, den mein Projekt benötigt, extrahiert und als Typoskriptdatei in das Projekt integriert. Das Problem dabei ist, dass Typskript diese Datei überprüft und jetzt viele Fehler für diese Datei ausgibt.

Für diese Situation wäre es großartig, den Kommentar /* ts:disable */ oben zu haben, damit das Typoskript weiß, dass wir uns nicht um mögliche Fehler in der Datei kümmern.

Bitte beachten Sie, dass mein Projekt keine Javascript-Dateien mehr festschreibt und selbst wenn dies der Fall wäre, würde der Build-Prozess komplizierter werden, wenn Sie versuchen, ein Javascript in den Flow aufzunehmen.

Hat jemand einen Rat, wie man mit Javascript-Code von Drittanbietern umgeht, der in einem Typoskript-Projekt gehostet werden muss?

Hat jemand einen Rat zum Umgang mit JavaScript-Code von Drittanbietern, der in einem Typoskriptprojekt gehostet werden muss?

migrieren Sie sie nicht. belassen Sie die .js-Dateien so, wie sie sind. Erstellen Sie stattdessen eine .d.ts-Datei für sie. dafür sind .d.ts-Dateien in jeder Hinsicht da.

Die .d.ts-Datei kann mit etwas so Grundlegendem beginnen wie:

declare var $: any;

dann fügen Sie es hinzu, wie Sie es für richtig halten und wenn Ihre Bedürfnisse wachsen.

Das ist eine gute Option, wenn ich js-Dateien festschreibe. Gibt es andere Optionen für Projekte, die js-Dateien ignorieren?

Das ist eine gute Option, wenn ich js-Dateien festschreibe. Gibt es andere Optionen für Projekte, die js-Dateien ignorieren?

Ich bin mir nicht sicher, ob ich die Frage verstehe. JS-Dateien werden standardmäßig ignoriert. Sie stimmen also dem Hinzufügen von Dateien zu. Auch hier ist meine Empfehlung, für externen Code, der nicht Ihnen gehört, oder für Legacy-Code, den Sie nicht ändern möchten, nicht die Mühe machen, ihn in TS zu konvertieren. Beginnen Sie damit, eine .d.ts-Datei für sie zu schreiben. Beginnen Sie dazu einfach mit any 's und fügen Sie dann nach und nach hinzu.

Ich hätte sagen sollen, dass die js-Dateien nicht in das Git-Repository übertragen werden, daher der Grund, den Code in eine ts-Datei zu packen. Wie auch immer, ich werde versuchen, den von Ihnen erwähnten Weg zu gehen und das Commit dieser js-Dateien zu erzwingen.

Sie müssen die .js-Dateien nicht festschreiben. Nehmen wir an, Sie verwenden eine Abhängigkeit Say Reagieren. Normalerweise werden Sie react-0.12.0.js in Ihrem Repository nicht festschreiben, aber Sie möchten es verwenden. Normalerweise würden Sie dies beispielsweise in ein Skript-Tag von einem CDN einfügen. Nehmen wir auch an, dass @types/react nicht existiert oder Sie es nicht verwenden möchten. Fügen Sie also in Ihrem Projekt eine neue Deklarationsdatei hinzu, nennen Sie sie declarations.d.ts und fügen Sie hinzu:

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

Dies teilt dem Compiler mit, dass es ein Modul namens "react" gibt, und es wird es einfach verwenden, es müssen keine .js-Dateien eingeschlossen werden.

Wenn ich also ein kleines Stück Javascript verwenden möchte (das nicht über npm/CDN verfügbar ist) und ich mich entscheide, es in meine Codebasis zu übertragen, habe ich 2 Möglichkeiten:

Option 1 : Behalten Sie den Originalcode als .js Datei bei und pflegen Sie eine .d.ts Datei, um Typen zu verarbeiten.

Ich denke, das funktioniert nicht für @jmlopez-rod, weil er keinen Javascript-Code in sein Repository übertragen möchte, und selbst wenn er es täte, sagte er, es würde seinen Build-Prozess kompliziert machen.

Option 2 : Wickeln Sie das Javascript in Typoskript ein und behandeln Sie alle Fehler des Typoskripts.

Dadurch wird der "komplizierte Build-Prozess" umgangen, da der Code wie Typoskript behandelt wird ... aber jetzt haben wir Typoskriptfehler und sind zur ursprünglichen Diskussion in diesem Thementhread zurückgekehrt. Ist dies ein gültiger Anwendungsfall, um Typoskriptfehler deaktivieren zu können?

Ich denke, das funktioniert nicht für @jmlopez-rod, weil er keinen Javascript-Code in sein Repository übertragen möchte, und selbst wenn er es täte, sagte er, es würde seinen Build-Prozess kompliziert machen.

Ich bin mir nicht sicher, warum es Ihren Build-Prozess erschwert. Sie haben eine Datei "library.js" und "website.js" , Sie beschließen "website.js" nach "website.ts" zu verschieben, rufen Sie einfach tsc website.ts --outFile website.js und jetzt sind wir wieder da, wo alles ist begann mit zwei .js-Dateien. Verstehe also nicht, warum es komplizierter ist als zuvor. Es ist nur ein zusätzlicher Bauschritt am Anfang der Kette.

Dadurch wird der "komplizierte Build-Prozess" umgangen, da der Code wie Typoskript behandelt wird ... aber jetzt haben wir Typoskriptfehler und sind zur ursprünglichen Diskussion in diesem Thementhread zurückgekehrt. Ist dies ein gültiger Anwendungsfall, um Typoskriptfehler deaktivieren zu können?

Ich bin mir nicht sicher, ob ich ganz verstehe, warum Sie sich entschieden haben, diese Datei auf ts umzustellen und sie in Ihr Projekt zu integrieren, Typen daraus in Ihre anderen Komponenten fließen zu lassen, sie zusammen mit Ihrem Code zu erstellen und sie dennoch an einen anderen Standard zu halten.

Vielleicht wäre hier ein Beispiel hilfreich. Wie @RyanCavanaugh bemerkte , scheint es mir, dass all diese Probleme gut definierte Möglichkeiten haben, dem Compiler die Typen mitzuteilen und Fehler zu vermeiden, anstatt Fehler alle zusammen zu deaktivieren und das Baby mit dem Bade zu werfen.

Ich konnte nicht verstehen, warum diese Ambient-Deklaration bei mir nicht funktioniert.
Ich habe die Pfaddefinition für die tsconfig.json bereits so definiert
"paths": { "js-xlsx": ["./xlsx.d.ts"] }
aber immer noch komme ich auf den Fehler "Modul nicht gefunden".
Ich habe versucht, 'fs', 'fs-extra' hinzuzufügen und dass 'js-xlsx'-Bibliotheken alle nicht auf meine Ambient-Deklarationen, Castings oder das Hinzufügen von Typen wie hier geantwortet haben declare var $: any;
@mhegazy

Sie müssen die .js-Dateien nicht festschreiben. Nehmen wir an, Sie verwenden eine Abhängigkeit Say Reagieren. Normalerweise werden Sie in Ihrem Repo keine React-0.12.0.js übertragen, aber Sie möchten es verwenden. Normalerweise würden Sie dies beispielsweise in ein Skript-Tag von einem CDN einfügen. Angenommen, @types/react existiert nicht oder Sie möchten es nicht verwenden. Fügen Sie also in Ihrem Projekt eine neue Deklarationsdatei hinzu, nennen Sie sie Declarations.d.ts und fügen Sie hinzu:

Modul "reagieren" deklarieren; // nur sagen, das Modul ist vom Typ any
Dies teilt dem Compiler mit, dass es ein Modul namens "react" gibt, und es wird es einfach verwenden, es müssen keine .js-Dateien eingeschlossen werden.

Übrigens weiß ich, dass die fs-extra-Bibliothek die Typdefinition wie @types/fs-extra hat und für die js-xlsx-Bibliotheken haben wir ts-xlsx-Bibliotheken, aber das ist so seltsam, dass diese Tricks bei mir nicht funktionieren :(

Übrigens weiß ich, dass die fs-extra-Bibliothek die Typdefinition wie @types/fs-extra hat und für die js-xlsx-Bibliotheken haben wir ts-xlsx-Bibliotheken, aber das ist so seltsam, dass diese Tricks bei mir nicht funktionieren :(

Ich denke, da ist noch etwas anderes mit Ihrem Projekt los.

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

ja vielleicht, aber das Hauptproblem, das ich nicht verstehen konnte, ist, warum ich Compiler-Warnungen mit den angegebenen Methoden nicht unterdrücken konnte. Übrigens habe ich https://github.com/AngularClass/angular2-webpack-starter , Basis für mein Projekt

Fehler zu unterdrücken bedeutet nicht unbedingt, Anti-Patterns einzuführen.

Ich erhalte einen falschen Fehler,

error TS1005: '{' expected.

auf diesem vollkommen feinen JSX:

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

Es beschwert sich, dass die Vorlagenzeichenfolge { . Dies sollte im Idealfall behoben sein, aber bis dahin möchte ich den Fehler aus gutem Grund unterdrücken können.

@trusktr , dieser Fehler ist ein Parse-Fehler. das Unterdrücken ändert nichts an der Tatsache, dass der Compiler den Code ab diesem Zeitpunkt nicht mehr versteht und sich die Form der restlichen Datei in einem undefinierten Zustand befindet. das bedeutet, dass selbst wenn dieser Fehler gedämpft ist, die abgeleiteten Typen sowie andere Fehler, die in dieser Datei oder anderen generiert werden, nicht korrekt sind.

Das gesagt. Laut JSX-Spezifikation :

JSXAttributeValue :

" JSXDoubleStringCharactersopt "
' JSXSingleStringCharactersopt '
{ Zuweisungsausdruck }
JSXElement

Ich fürchte also, der Fehler ist korrekt und ein JSX-Attribut kann kein Zeichenfolgenvorlagenliteral haben. du kannst stattdessen absolteSize = {...} verwenden

Dieser Fehler ist ein Parse-Fehler

Ja, deshalb sollte es behoben werden.

Die Ausgabe ist absoluteSize: "0, " + this.MENU_BAR_HEIGHT + ", 0" , was dem Compiler sagt, dass es in Ordnung ist.

Oh. Dann bitte ich um Entschuldigung. Ich habe deinen Kommentar nicht verstanden. Ich dachte, Sie wollten den Fehler zum Schweigen bringen.

Das habe ich, aber du hast recht, vielleicht sollte ich besser damit leben, nur {} hinzuzufügen.

In TS 2.1 (VS2017 RC) erhalten wir gemeldete Warnungen aus Bibliotheken-JS-Dateien (im Ordner /Scripts) - wie TS7027. Es wäre schön, Warnungen/Fehler entweder aus Bibliotheksdateien unterdrücken zu können oder sie zumindest in einer Art globaler Unterdrückungsdatei (ähnlich wie C# GlobalSupressions.cs) zu unterstützen.

In TS 2.1 (VS2017 RC) erhalten wir gemeldete Warnungen aus Bibliotheken-JS-Dateien (im Ordner /Scripts) - wie TS7027.

Für nicht erreichbaren Code (TS 7027) legen Sie --allowUnreachableCode oder geben Sie ihn in Ihrem tsconfig.json .

Aber ist es möglich, es nur auf Bibliotheksdateien anzuwenden. Denn für "meinen Code" brauche ich ihn !

Wenn Sie --alowJs , wird es zu Ihrem Code. der Compiler saugt es ein, transpiliert es zum vorgeschlagenen Ziel, verkettet es, wenn Sie --outFile .. es hat nur eine .js-Erweiterung. Wenn es sich um "Bibliotheks" -Code handelt, würde ich empfehlen, eine .d.ts-Datei dafür zu erstellen und diese stattdessen einzuschließen.

Mir ist nicht bekannt, dass wir --allowJs eingeschaltet haben - in VS2015 squiggle das genau gleiche Projekt nicht jquery.js, reakt.js-Dateien, die in Skripten sitzen (und tatsächlich nur von der HTML-Seite referenziert werden)

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

In meinem Fall ist die erste Zeile in TypeScript geschrieben, die zweite Zeile in JavaScript. Sie werden in verschiedenen Kontexten ausgeführt und ich möchte keinen JavaScript-Code ändern.
Also brauchen wir eine neue Option wie /* ts-disable */ /* ts-enable */ (eslint-ähnlich)

In meinem Fall ist die erste Zeile in TypeScript geschrieben, die zweite Zeile in JavaScript. Sie werden in verschiedenen Kontexten ausgeführt und ich möchte keinen JavaScript-Code ändern.

Ich bin mir nicht sicher, was Sie mit "zweite Zeile in JavaScript geschrieben" meinen? Übergeben Sie die gesamte Anweisung an den Compiler oder nicht?

Ich bin mir nicht sicher, was Sie mit "zweite Zeile in JavaScript geschrieben" meinen? Übergeben Sie die gesamte Anweisung an den Compiler oder nicht?

Ich möchte diesen Code nicht ändern, da er unverändert an den Selenium-Server übergeben werden sollte .

Ich möchte diesen Code nicht ändern, da er unverändert an den Selenium-Server übergeben werden sollte.

Wenn sich diese in einer .ts-Datei befindet, wird sie vom Compiler umgewandelt. Der Compiler entfernt die Typanmerkungen für Sie.

Unabhängig davon benötigen Sie für dieses Beispiel nur declare var browser: any; und Sie sollten keine Fehler erhalten. Siehe Spielplatz für ein Beispiel.

Wenn sich diese in einer .ts-Datei befindet, wird sie vom Compiler umgewandelt. Der Compiler entfernt die Typanmerkungen für Sie.

Ich benötige eine Garantie, dass ein bestimmter Code im IE6 und anderen alten Browsern unmanipuliert ausgeführt wurde.
Node.js folgt beispielsweise dem CommonJS-Modulsystem, aber mein require ist eine benutzerdefinierte Funktion, die von anderen Entwicklern auf ihren Seiten definiert wurde. Deshalb möchte ich diesen Code ohne Nach- und Vormodifikationen einbinden. Es ist wichtig für mich und mein Team.

Unabhängig davon müssen Sie für dieses Beispiel lediglich var browser deklarieren: any; und Sie sollten keine Fehler bekommen. Siehe Spielplatz für ein Beispiel.

Tatsächlich ist das Browser-Objekt das beliebteste Objekt in meinem Projekt und es gibt keinen Grund, es zu ignorieren. Die Methode browser.execute hat auch eine eigene Typdeklaration.

jetzt bin ich mir nicht sicher ob ich das Problem verstanden habe. was ist der fehler, den du bekommst?

Mein Code wird in verschiedenen Kontexten ausgeführt: Knoten und Browser. Die aktuellen Probleme für den zweiten Kontext sind Typannotationen und Codeänderungen.

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); 
});

Hier ist eine einfache Implementierung der Methode browser.executeAsync :

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

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

Wie Sie sehen, verwende ich TypeScript für Integrationstests.

Wie lautet die Fehlermeldung?

Standardfehler:

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

Und so weiter...

Definiere require richtig.

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

Definieren Sie Bedarf richtig.

Ich kann nicht. In meinem Fall enthält die Methode executeAsync Code für Projekte von Drittanbietern und es gibt verschiedene Variationen für solche require s. Der obige Code ist nur eine Funktion von Hunderten.
Mein Wunsch ist sehr einfach – lass mich Code ausschließen, wenn ich ihn brauche :)

Sie können declare function require(v: string[]): any; lokal ablegen. z.B:

// 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);
});

Sie können bei Bedarf auch einfach auf any werfen:

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);
});

Dies sollte identischen Code erzeugen.

In meinem Fall habe ich eine private (nicht exportierte) abstrakte Klasse, die nur um zwei Klassen erweitert werden soll:

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() { ... }
  ...
}

Verwendungszweck:

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

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

Aber bei Methode fromConfig() erhalte ich "Kann keine Instanz der abstrakten Klasse 'Parent' erstellen:

Spielplatzcode

  • Ich kann die statischen Methoden duplizieren und eine gemeinsame Funktion aufrufen, klingt aber ziemlich dumm, wenn ich bereits einen funktionierenden Code habe.
  • Ich kann die Klasse nicht abstrakt machen, weil Unterklassen die Methodenimplementierung anwenden.
  • Ich kann die abstrakten Methoden entfernen, aber ich verwende sie, um dieselbe Schnittstelle für Unterklassen zu erzwingen.
  • Ich kann eine separate Schnittstelle verwenden, um sie zu erzwingen, aber dann passt die Superklasse nicht in die Schnittstelle und es ist der Typ, der von der statischen Methode zurückgegeben wird.
  • Ich habe nicht die Absicht, die statische Methode für die abstrakte Klasse aufzurufen, ich möchte nur, dass sie eine andere Klasse in den verschiedenen Unterklassen instanziiert

Der Compiler erzwingt nicht, dass abgeleitete Klassenkonstruktoren dieselbe Signatur wie die Basis haben. mit anderen Worten, der abgeleitete Klassenkonstruktor kann mehr erforderliche Argumente haben als die Basis. Die Verwendung von new this() davon aus, dass alle abgeleiteten Konstruktoren keine erforderlichen Parameter haben; und das ist etwas nicht überprüfbares.

Wenn Sie sicher sind, dass dies richtig ist, sollten Sie die Übertragung als new (<any>this)(x, y); Betracht ziehen

Guter Punkt, das habe ich nicht gesehen. Ihr Vorschlag funktioniert tatsächlich, ich werde die Gefahren berücksichtigen, danke.

Gibt es eine Möglichkeit, Module ... was resolved to ..., but '--allowJs' is not set zum Schweigen zu bringen? In meinem Anwendungsfall gibt es ein Build-System, das sich darum kümmert, und ich muss nicht meinen gesamten Code durch TSC übergeben, daher möchte ich diese Fehler stummschalten.

'Modul "someModule" deklarieren;' in einer Ihrer .d.ts-Dateien.

Oder installieren Sie das passende @types- Paket, falls vorhanden.

Ich habe ein anderes Beispiel, wann dies nützlich wäre:

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>
);

Dies löst einen Fehler aus, da onTouchStart keinen String als Parameter akzeptiert, der wahr ist. onTouchStart='' behebt jedoch fehlerhaftes CSS-Verhalten auf Touch-Geräten im Zusammenhang mit bestimmten CSS-Regeln. Ich möchte diesen Fehler nicht global deaktivieren oder einige JSX-Typen neu definieren. Ich möchte nur in dieser Zeile diesen Fehler beseitigen.

onTouchStart={<any>''}

Das behebt es eigentlich nicht.
Ich bekomme diesen Fehler:
error
Es ist unter der tsx-Syntax kaputt

onTouchStart={'' as any} , eher (vergessen, dass JSX eine alternative Assertionssyntax verwendet)

@RyanCavanaugh wäre generierter Code ein legitimer Anwendungsfall für diese Funktion? Ich verwende Swagger-Codegen , um einen API-Client für einen Knotendienst zu erstellen. Ich verwende auch die Typen des generierten Clients in meinem Server, da es Swagger-Definitionen in TypeScript-Schnittstellen umwandelt. Dies ist der einfachste Weg, um sicherzustellen, dass ich meinen eigenen Swagger-Vertrag einhalte.

Der generierte Code ist jedoch etwas seltsam und enthält Blöcke wie diese:

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

Dies gibt einen Fehler aus, wenn strictNullChecks ist, daher habe ich das Flag für das gesamte Projekt deaktiviert. Was nervt. Ich möchte das generierte Typoskript nicht parsen und ändern, aber ich wäre bereit, etwas wie <tsc strictNullChecks=false /> am Anfang der Datei einzufügen (ähnlich dem @alexanderbird ).

Wäre dies nicht eine Änderungsanforderung an den Swagger-Code-Generator, um striktNullChecks-kompatiblen Code zu erzeugen?

@mhegazy sicher - aber das ist nur ein Beispiel für so etwas. Es gibt viele Möglichkeiten, wie die Codegenerierung in TypeScript nützlich ist (mehr als in JavaScript). Idealerweise gäbe es also eine Möglichkeit, die Leute nicht dazu zu zwingen, ihre eigenen Projekte auf die Standards ihres generierten Codes herunterzuschleppen.

Aber sie sind :) Der Code, den Sie von Ihrem Auto-Generierungs-Tool erhalten, führt zu Typen, die in Ihre Kompilierung einfließen. Wenn das Codegenerierungstool --strictNullChecks ignoriert, beobachtet Ihr Code nicht irreführende Typen.
Das Deaktivieren von Checks dämpft nur den Feueralarm. Das Problem ist nicht der Alarm, sondern die Ursache des Feuers.

@mhegazy Ich bin damit einverstanden, den Feueralarm in Code zu

Wie wäre es mit einem weniger umstrittenen Beispiel - was ist, wenn der generierte Code ein unbenutztes Local hat? Das schadet meinem Code nicht - außer in dem Fall, in dem ich noUnusedLocals in tsconfig deaktivieren muss - was ich jetzt tue.

Wie wäre es mit einem weniger umstrittenen Beispiel - was ist, wenn der generierte Code ein unbenutztes Local hat? Das schadet meinem Code nicht - außer in dem Fall, in dem ich noUnusedLocals in tsconfig deaktivieren muss - was ich jetzt tue.

Wenn Ihnen der generierte Code egal ist, sollte er in .js mit einem begleitenden .d.ts vorliegen. Auf diese Weise können Sie es überprüfen, müssen es jedoch nicht kompilieren.

der Typoskript-Compiler scheint Underscore.js-Mixins nicht zu mögen, die mit Kette verwendet werden.

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

....

someVal = _.chain(someArray)
.sortFunktion()
.otherChainFunc()
.Wert();

...

Ein ziemlich einfaches Beispiel ist, wenn Sie einen Listener für Klick erstellen, zum Beispiel mit @HostListener() für Angular, wie folgt:

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

Wenn ich noUnusedLocals aktiviere,

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

Kann ich das irgendwie vom Compiler ignorieren lassen?

@JeremyCarlsten

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

sieht nach ungültigem Code aus.

@leocaseiro Warum muss es privat sein? In diesem Fall ist onClick eine Methode, die angle am Ende verwendet. Ein ähnliches Problem tritt immer auf, wenn wir private Variablen deklarieren, die wir in einer Vorlage verwenden. Wenn Sie sie in der Vorlage verwenden, machen Sie die Variablen einfach öffentlich. Es ist sinnvoll, da Sie sie von Angular verwenden lassen.

Hallo @jmlopez-rod, du hast recht.

Interessant, dass es als Öffentlichkeit jetzt vorbei ist! Ich schätze deine Hilfe sehr.

@leocaseiro public ist die Standard-Sichtbarkeitsstufe, sodass Sie sie nicht angeben müssen.

Entschuldigung im Voraus, wenn sich das negativ anhört – ich habe vielleicht etwas verpasst (neu bei TS).
Ein weiteres Beispiel (ich verwende TS nur, um ES5 zu produzieren - kein Casting, Deklarieren, Interfacing)

// 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;
}

wahr bei der Erstellung, aber nicht bei der Verwendung – MOM mich nicht!

Genau dafür wurde TypeScript entwickelt. Wenn Sie keine Typen und kein Casting verwenden möchten, warum verwenden Sie dann TypeScript? Wie in diesem Thread mehrmals erwähnt, wird der Code immer noch ausgegeben, sodass Sie Fehler bereits auf eigene Gefahr ignorieren. Warum sollte man versuchen, TypeScript zu verdummen, zu welchem ​​Zweck?

Warum sollte man versuchen, TypeScript zu verdummen, zu welchem ​​Zweck?

Es geht darum, ein Team von ES5 => ES6 (Babel oder TS) => TS in seiner ganzen Pracht – in Babyschritten – zu verschieben.

Mein Eindruck war, dass TS eine Ergänzung zu JS ist, die es Ihnen ermöglicht, auf Ihrem Niveau einzusteigen.
Der Grund für meine Beschwerde ist, dass das bereitgestellte Dummy-Beispiel einen Fehler auslöst und daher _tut
ES5_ nicht produzieren. IMO-Passing-Flusen sollten nicht zwingend zu transpilieren sein.

Sofern Sie keine Fehlerausgabe haben, wird es ausgegeben. Es produziert also ES5.

Hat nicht geklappt – auf Babel umgestellt – es hat funktioniert

tsc kann so konfiguriert werden, dass die Ausgabe unabhängig von Typfehlern ausgegeben wird, sehen Sie sich die Option noEmitOnError .

Wenn Sie ts-loader verwenden, hat es auch eine neue Option transpileOnly bei der es einfach transpiliert und keine Fehler anzeigt.

@trusktr danke - ich werde es versuchen :-)

Fehler blockieren weder die Generierung von Ausgaben noch die Werkzeugausstattung

Das ist nicht wahr. Wir haben ein (ziemlich übliches - es kommt vom Starter) Setup in Webpack, das im Produktions-Build abstürzt und nichts ausgibt. Und so sollte es auch sein - Compiler meldet Fehler, Programmierer geht zurück und behebt sie. Warum Typen verwenden, wenn das ganze Team sie ignoriert, weil der Build "funktioniert"? In ähnlicher Weise funktioniert die automatische Aktualisierung nicht, wenn tsc nicht kompiliert werden kann (das Plugin ist absichtlich so geschrieben - es wird nicht aktualisiert, wenn Ihr Code falsch ist [oder vom Compiler als falsch angesehen wird]).

Das Unterdrücken von Fehlern ist nützlich, wenn ein Fehler in tsc vorliegt. Das sollte zB kompilieren:

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

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

aber in der aktuellen TS-Version schlägt es fehl.

Edit: Funktionsaufruf behoben (falsche Zeile kopiert)

Von

a.isEmptyObject({a: 1});

was meinen Sie

a.isEmpty({a: 1});

?

Oh ja. Falsche Zeile kopiert :/.

Das Unterdrücken von Fehlern ist nützlich, wenn ein Fehler in tsc vorliegt.

Ein Fehler, der Emittieren verhindert, sollte behoben werden. Es ist sehr unwahrscheinlich, dass die Möglichkeit, einen Fehler zu ignorieren, dazu führen würde, dass tsc plötzlich etwas ausgibt, wenn es einen Fehler hat, der zum Absturz führt.

Ich habe einen Import, der so aussieht:

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

Ich benutze zuerst TypeScript, dann Babel. Ich habe ein Babel-Plugin, das * bei Importen als Glob-Muster behandelt. TypeScript gibt einen Fehler aus, der sich über .ts beschwert, und wenn .ts entfernt wird, kann es das Modul nicht finden.

Ich bin mir nicht sicher, wie ich das lösen soll, aber mein erster Gedanke war, die Fehler in Bezug auf diese Zeile zu unterdrücken. Ich habe versucht, die Modulzuordnung in der Konfiguration durchzuführen, aber * wird auch dort als Platzhalter behandelt und kann nicht mit Escapezeichen versehen werden.

@lukescott in einer .d.ts im Rahmen des Compilers:

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

Ein weiteres Beispiel, wie dies nützlich wäre:

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

Das getPeerCertificate sagt, dass es aufgrund fehlerhafter Definitionen im Knoten https ( auch this ) nicht existiert.

Es kompiliert und funktioniert immer noch mit der großen roten Unterstreichung, aber es wäre sehr schön, dies zu tun

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

@trusktr
Hoppla sieht so aus, als hätte ich die Syntax beim Konvertieren aus dem Prod-Code durcheinander gebracht. Hier ist ein js-Plunk von dem, was ich zu beschreiben versuchte. Vielleicht eher ein Problem mit den Unterstrichdefinitionen. Aber wenn eine Bibliothek eines Drittanbieters Probleme mit dem ts-Compiler verursacht, sollten wir diese Codezeile nicht ignorieren können?

+1. Dies ist für Tests nützlich, da ich sicherstellen muss, dass mein Code einen Fehler auslöst, wenn er an etwas übergeben wird, das er nicht erwartet.

Diese nützliche Funktion wäre nur die Verallgemeinerung von ! für möglicherweise Nullobjekte.

Wenn ich eine Bibliotheksdatei in ein Projekt bringen möchte (zB Chartjs), speichere ich sie oft als TS-Datei (ich behalte gerne alle Quelldateien als TS und kompiliert als JS) und importiere sie mit einem dreifachen Schrägstrich ref in den TS Datei, die es erfordert. Allerdings beschwert sich das TypeScript dann endlos über Fehler in dieser Datei (natürlich da es sich lediglich um eine als TS abgespeicherte Standard-JS-Datei handelt).

Die Möglichkeit, Folgendes hinzuzufügen:

/*ts-errors-disable*/ zum Anfang der Bibliotheksdatei und /*ts-errors-enable*/ zum Ende würde die Ausgabe von Fehlern reduzieren, die nicht relevant sind, aber es Entwicklern trotzdem erlauben, alle Quelldateien als TS zu behalten.

Oder sollte ich die Dinge einfach grundlegend anders machen?

@benfrain Nun, es wäre besser, die entsprechende TypeScript-Definitionsdatei zu installieren, falls vorhanden ( npm install --save-dev @types/mylibrary ) oder eine eigene _.d.ts_-Datei mit dem Typ any für Ihren Bibliotheksnamensraum zu erstellen /Hauptklasse zuerst:

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

Ich habe eine Frage. Zuerst der Code und der Fehler, den TypeScript hervorhebt:

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, '')
  }
}

Das Problem, das ich habe, ist, dass ich den Dekorator @Input deklarieren muss, damit dem Attribut eine Zeichenfolge übergeben werden kann. Aber ich kümmere mich nur um den Wert dieser Zeichenfolge, wenn sie sich ändert. Und ich kann den vorherigen und aktuellen Wert abrufen, wenn ich das Änderungsereignis handhabe.

Können wir jetzt ein // ts-ignore ? Oder gibt es eine andere Möglichkeit das gut zu lösen?

@uglow warum ist attrName privat? Dies ist eine Variable, die Angular so ändert, dass Sie damit einen Wert erhalten. Daher muss es öffentlich sein.

@jmlopez-rod Ich habe es in öffentlich geändert, aber das ändert nichts am Problem. TS sagt, dass es eine unbenutzte Variable ist.

Ich verwende TS 2.4.1, nachdem ich es öffentlich gemacht habe, gibt Typescript den Fehler nicht mehr aus.

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

Nach:
screen shot 2017-07-26 at 9 53 39 am

Ich verwende 2.3.3. 2.4.1 probiere ich mal aus. Danke 😊

Dies sollte enthalten sein. Ich arbeite mit einer benutzerdefinierten js-Engine, die es einer einzelnen .js-Datei ermöglicht, einen Wert zurückzugeben. Siehe mein Wesentliches für ein Beispiel . Ich verwende TS, um meine .js-Dateien zu generieren, und natürlich weiß TS nichts davon und wirft:

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

@mhegazy Ich bin auf verschiedene Arten auf diese Art von Problem

Meine aktuelle Situation (der gesamte Ablauf nimmt den Deklarationsmodus an):

  • Klassendekoratoren erfordern eine Klassendeklaration (keinen Klassenausdruck) und ich bin in einer Funktion - im Prinzip könnte dies behoben werden, aber das ist heute nicht der Fall.
  • ok, kein Problem, ich mache den Ausdruck zu einer Deklaration
  • kein Würfel, die Deklaration hat jetzt einen unbenutzten Namen
  • ok kein problem ich schicke es zurück
  • keine Würfel, Return type of public method from exported class has or is using private name
  • ... ?

Im Grunde ist die Ursache hier, dass Ausdrücke nicht dekoriert werden können, aber es ist unvernünftig, alles zu löschen, um diese Funktionalität zu implementieren. In der Zwischenzeit ist es für mich sinnvoll, diesen Fehler einfach zu unterdrücken. Es wäre in Ordnung, wenn ich zum Unterdrücken eines Fehlers das zugehörige TypeScript-Problem finden und etwas wie // TS-LIMITATION:#9448 sagen müsste, obwohl ich vermute, dass dies aus Ihrer Sicht zu einer Vielzahl neuer sinnloser Probleme führen würde.

Es wäre mir sogar gut, wenn Sie gezielte Unterdrückungen für bekannte Probleme hinzufügen würden, auf die Sie noch nicht bereit sind, aber nur, wenn dies schnell und ohne zu großen Designaufwand ging (das würde den Mechanismus sinnlos machen :wink: )

Ich möchte keinen unerreichbaren Codefehler erhalten (wobei ich gerne "sei hier bei unerreichbarem Codefehler die Klappe" anmerke), wenn ich so etwas tue wie
if (false){ ...complicated debug code that I dont want to delete/forget... }

Dem TypeScript-Compiler fehlt also immer noch eine Option, um "die Klappe zu halten und andere Tools nicht durcheinander zu bringen". Es wäre wirklich nützlich für uns, diese Option über Kommentare und über Compiler-Schalter für bestimmte Dateien oder sogar Glob zu haben. Wir bleiben bei der Verwendung alter Versionen von Tools hängen, weil wir das automatische Neuladen nicht verlieren möchten (neuere Versionen werden nicht automatisch neu geladen, wenn Fehler vorhanden sind). Also deaktivieren wir entweder die fehlerhafte Option noImplicitAny (was ich wirklich nicht möchte, ich verwende TypeScript wegen der Typüberprüfung und mit erlaubtem impliziten bringt jedes TypeScript nicht so viel auf eine Tabelle) oder bleiben bei alten Versionen von Paketen. Ja, ich habe den Fehler sowohl im WebPack- als auch im AwesomeTypeScript- Loader

@polyglotinc if (!!false) {

@RyanCavanaugh Nun, im (!true) ... Ich habe diese nicht einmal als Möglichkeiten betrachtet, weil ich _(als Ex-Compiler-Autor)_ dem Compiler mehr Anerkennung in Bezug auf Konstante / Literal gegeben habe Ausdruck kollabiert... Ich glaube, ich dachte, wenn es sich um einen beschäftigten Körper mit if (false) würde, würde er wissen, dass if (!true) dasselbe ist!

@unional die SO- Frage könnte etwas klarer geschrieben werden und vielleicht brauchen wir deshalb den Compiler, um uns über mögliche Fehler zu informieren . Sehen Sie sich diesen Screenshot an, der den Fehler zeigt, den der Benutzer unterdrücken möchte

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

Beachten Sie, dass ich im Screenshot nur einen Fehler habe. Das liegt daran, dass ich bereits ein Problem behoben habe, das vom Compiler aufgefangen wurde.

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

Der Benutzer behauptet, dass handleArrow* werden, aber Typoskript sieht nicht, dass es verwendet wird. Was das Typoskript betrifft, könnte das this in this.handleArrowDown($event); jedes Objekt sein, das die Methode handleArrowDown . Mit der Pfeilfunktion weiß es jetzt, dass this die Instanz der Klasse ist und sieht daher, dass handleArrowUp verwendet wird.

Eine andere Möglichkeit: Verwenden Sie den falschen ersten Parameter this .

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

@jmlopez-rod Danke. Diese sind eine gute Alternative. Ich mag die Lösung function(this: SomeComponent, ...) {...} , weil sie am flexibelsten ist.

Die Pfeilfunktion funktioniert nicht, wenn keyHandlers kein Teil der Klasse ist:

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) {
    // ...
  }
}

Andererseits ist die Pfeilfunktion in diesem Zusammenhang am einfachsten.

Ich versuche, window.console für IE9 manuell festzulegen, um Fehler bei der Verwendung von console.log zu vermeiden:

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

Aber ich bekomme error TS2540: Cannot assign to 'console' because it is a constant or a read-only property. Gibt es eine Problemumgehung für diese Anwendungsfälle?

@amiraliakbari Sie können window als any Typ angeben , wodurch Sie die Typprüfung effektiv deaktivieren können:

(window as any).console = {};

Dies funktionierte für mich, um console.log global zu überschreiben/zu deaktivieren -- Beachten Sie, dass Project.logging zuvor definiert wurde

(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;
};

Dies war auch viel sauberer, als if Anweisungen in meinem gesamten Code zu platzieren, da ich einfach console.log wie gewohnt verwenden kann

Wie in #19109 erwähnt, haben wir immer noch nicht die Möglichkeit, einen bestimmten Fehler zu unterdrücken.

Wie in #19109 erwähnt, haben wir immer noch nicht die Möglichkeit, einen bestimmten Fehler zu unterdrücken.

Ich denke, das in dieser Ausgabe beschriebene grundlegende Szenario wurde angegangen. Wir können ein neues Problem erstellen, um die globale Fehlerunterdrückung anhand der Fehlernummer zu verfolgen. Wir haben uns geweigert, Fehlercodes auf diese Weise zu verwenden, da sie keine Aussagekraft haben.

Erstellt #19139.

Diese Anweisung funktioniert nur pro Datei, oder? Ist es möglich, dass es über den Ordner funktioniert?

Die Anweisung soll jeweils für eine einzelne Zeile funktionieren. Wenn Sie eine Menge von Compiler - Fehler in Ihrem Projekt zu sehen, können Sie überprüfen, ob Sie streng weniger sollten Optionen Compiler , wie verlassen noImplicitAny off (dh Variablen sind implizit any , wenn nicht kommentiert). Sie könnten auch einige Dateien als JS belassen und allowJs aktivieren, aber checkJs deaktivieren.

Warum haben Sie dieses Thema geschlossen? Die Lösung fehlt noch! Warum führen Sie 2 Jahre lang sinnlose Diskussionen statt Integration eine richtige Fehlerunterdrückungsmöglichkeit?

@webia1 Vielleicht interessiert Sie #19139, das noch offen ist.

(Diesen Kommentar hier hinzufügen, da er für diejenigen nützlich sein könnte, die wie ich über dieses Problem stolpern)

Ich bin auf https://github.com/Microsoft/TypeScript/pull/21602 gestoßen und es könnte die Lösung sein.

Fügen Sie einfach // @ts-ignore zu Ihrem Code hinzu (oder sogar // @ts-ignore <some code error> , um nur den angegebenen Fehler zu ignorieren) .

Habe es hier mit TypeScript 2.7.2 getestet und es funktioniert!

(oder sogar // @ts-ignorenur den angegebenen Fehler ignorieren).

21602 wurde nicht zusammengeführt. Sie können nicht nur bestimmte Fehler ignorieren.

@RyanCavanaugh du hast recht! Ich habe meinen Kommentar aktualisiert. Vielen Dank!

Hier angekommen, um den Fehler TS2339 zu unterdrücken.

document.getElementById('theme-admin').disabled = false; /* tslint:disable */
document.getElementById('theme-member').disabled = true; /* tslint:disable */
War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

Roam-Cooper picture Roam-Cooper  ·  3Kommentare

weswigham picture weswigham  ·  3Kommentare

kyasbal-1994 picture kyasbal-1994  ·  3Kommentare

MartynasZilinskas picture MartynasZilinskas  ·  3Kommentare

dlaberge picture dlaberge  ·  3Kommentare