web-dev-qa-db-ja.com

特定のTypeScriptコンパイルエラーを無視しますか?

コンパイル時に特定のTypeScriptエラーを無視する方法があるかどうか疑問に思っていますか?

私は基本的に、大規模なプロジェクトを持つほとんどの人がthisキーワードを使用することに関して同じ問題を抱えており、すべてのクラスメソッドをコンストラクターに入れたくありません。

だから私はそのような例を持っています:

TypeScriptの例

これは完全に有効なJSを作成し、thisキーワードの問題を回避できるようですが、例でわかるように、TypeScriptコンパイラはそのコードを次のようにコンパイルできないことを示しています。キーワードthisはそのスコープ内では無効です。ただし、問題のないコードが生成されるため、エラーである理由がわかりません。

それで、特定のエラーを無視するように指示する方法はありますか? thisキーワードを管理するための良い方法があると確信していますが、現在はかなり悲惨です。

==編集==

(この質問の文脈と部分的な暴言を気にしない限り読まないでください)

これらすべてにコンテキストを追加して、私が単なる仕事ではないこと(多くの人がまだ私だと思っていると確信しています)と、これらを許可したい理由がいくつかあることを示します。通過するエラー。

TypeScriptcurrentthisのいくつかの主要な問題(imo)を強調する私が以前に行ったいくつかの質問があります実装。

TypeScriptでlawnchairを使用

TypeScriptでの子スコープの問題

https://TypeScript.codeplex.com/discussions/42935 (そして私が下に書いたいくつかのコメント)

私が抱えている根本的な問題は、すべてのロジックが一貫したスコープ内にあることを保証する必要があることです。ノックアウト、jQueryなどおよびクラスのローカルインスタンス内のものにアクセスできる必要があります。私はこれをJavaScriptのクラス宣言内のvar self = this;で行っていましたが、うまく機能しました。これらの前の質問のいくつかで述べたように、今はそれを行うことができないので、スコープを保証できる唯一の方法はラムダメソッドを使用することであり、クラス内のメソッドとしてこれらの1つを定義できる唯一の方法はコンストラクター内です。この部分は個人的な好みに大きく依存しますが、その構文を使用することは単なる回避策ではなく、推奨されるパターンとして分類されていると人々が考えるのは恐ろしいことです。

TypeScriptがアルファ段階にあり、多くの変更が行われることはわかっています。thisを処理するためのより良い方法が得られることを願っていますが、現在はどちらかです。 TypeScriptを機能させるためだけにすべてを大混乱にするか(これはTypeScriptに移行する数百のファイル内にあります)、またはこの場合はコンパイラよりもよく知っている呼び出しを行います(非常に危険です)。私は自分のコードをきれいに保つことができ、うまくいけば、これを処理するためのより良いパターンが出てきたら、それを移行することができます。

また、余談ですが、多くの人がTypeScriptが新しいJavaScript機能と既知の構文にできるだけ近づこうとしているという事実を愛していることを知っていますが、TypeScriptはJavaScriptの次のバージョンではないので最新かつ最高の公式JavaScript実装を使用したい人はまだそうすることができるので、言語に構文糖衣構文を追加することに問題はありません。

15
Grofit

thisに関する作成者の特定の問題は解決されたようですが、エラーを無視することについて、そしてここでエラーを無視する方法を探している人のために、質問が提起されています。

TypeScript 2.6(2017年10月31日にリリース)の時点で、エラーを適切に修正するか、ここですでに提案されているようなより適切な回避策を使用することができない場合は、 からのすべてのエラーを無視する方法があります。ターゲット行の前に// @ts-ignoreコメントを使用する特定の行

言及されたドキュメント は十分に簡潔ですが、要約すると:

// @ts-ignore
const s : string = false

この行のエラー報告を無効にします。

ただし、これは、エラーを修正するとき、または(x as any)のようなハックを使用することが、行のすべての型チェックを失うよりもはるかに厄介な場合の最後の手段としてのみ使用する必要があります。

特定のエラーの指定については、現在(2018年半ば)の状態について、ここで 、設計会議ノート(2018年2月16日)およびその他のコメント で説明されています。

「結論なしまだ

そして、この微調整を導入することに強い反対があります。

9
stsloth

提起されたあなたの質問は XY問題 だと思います。あなたが目指しているのはクラスメソッドのいくつかが正しいthisコンテキストを持つことが保証されていることをどのように確認できますか?

その問題について、私はこの解決策を提案します:

class LambdaMethods {
    constructor(private message: string) {
        this.DoSomething = this.DoSomething.bind(this);
    }

    public DoSomething() {
        alert(this.message);
    }
}

これにはいくつかの利点があります。

まず、あなたは何が起こっているのかを明確にしています。ほとんどのプログラマーは、コード生成に関してメンバー構文とメソッド構文の違いが何であるかについての微妙なセマンティクスをおそらく理解しないでしょう。

次に、コンストラクターを見ると、どのメソッドがthisコンテキストを保証するかが非常に明確になります。重要なのは、パフォーマンスの観点から、すべてのメソッドをこのように記述したくはなく、絶対に必要なメソッドだけを記述したいということです。

最後に、クラスのOOPセマンティクスを保持します。実際にはDoSomethingの派生クラス実装からsuper.DoSomethingを使用できます。

5
Ryan Cavanaugh

矢印表記なしで関数を定義する標準的な形式をご存知だと思います。まったく同じコードを生成するが、コンパイルエラーがない別のTypeScript式があります。

class LambdaMethods {
    private message: string;
    public DoSomething: () => void;

    constructor(message: string) {
        this.message = message;
        this.DoSomething = () => { alert(this.message); };
    }
}

では、なぜこれは合法であり、もう1つは合法ではないのでしょうか。仕様によると:an arrow function expression preserves the this of its enclosing context。したがって、宣言されたスコープからのthisの意味を保持します。しかし、クラスレベルで関数を宣言するthisは実際には意味がありません。

これは、まったく同じ理由で間違っている例です。

class LambdaMethods {
    private message: string;

    constructor(message: string) {
        this.message = message;
    }

    var a = this.message;  // can't do this
}

初期化子がコンストラクターと組み合わされて機能する方法は、信頼できない実装の詳細です。変更される可能性があります。

このキーワードを管理するための良い方法があると確信していますが、現在はかなり悲惨です。

TypeScriptの(私が大好きな)高レベルの目標の1つは、JavaScript言語を拡張して操作することであり、それと戦うことではありません。 thisの動作方法は注意が必要ですが、学ぶ価値があります。

2