.ts
ファイルと比較して、.js
ファイルでのチェックの動作にはいくつかの注目すべき違いがあります。
プロパティはクラス本体での代入から推論されます
ES2015には、クラスにプロパティを宣言する手段がありません。プロパティは、オブジェクトリテラルのように動的に割り当てられます。
.js
ファイルでは、コンパイラはクラス本体内のプロパティ代入からプロパティを推論します。プロパティの型は、コンストラクターで指定された型になります。ただし、コンストラクターで定義されていない場合、またはコンストラクターの型が未定義またはnullの場合は除きます。その場合、型はこれらの代入におけるすべての右辺値の型の結合になります。コンストラクターで定義されたプロパティは常に存在すると見なされますが、メソッド、ゲッター、またはセッターでのみ定義されたプロパティはオプションと見なされます。
jsTry
classC {constructor() {this.constructorOnly = 0;this.constructorUnknown =undefined ;}method () {this.Type 'boolean' is not assignable to type 'number'.2322Type 'boolean' is not assignable to type 'number'.constructorOnly = false;this.constructorUnknown = "plunkbat"; // ok, constructorUnknown is string | undefinedthis.methodOnly = "ok"; // ok, but methodOnly could also be undefined}method2 () {this.methodOnly = true; // also, ok, methodOnly's type is string | boolean | undefined}}
プロパティがクラス本体で設定されない場合、それらは不明と見なされます。クラスに読み取り専用のプロパティがある場合は、JSDocを使用してコンストラクターに宣言を追加して型を指定してください。後で初期化する場合、値を指定する必要はありません。
jsTry
classC {constructor() {/** @type {number | undefined} */this.prop =undefined ;/** @type {number | undefined} */this.count ;}}letc = newC ();c .prop = 0; // OKType 'string' is not assignable to type 'number'.2322Type 'string' is not assignable to type 'number'.c .count = "string";
コンストラクター関数はクラスと同等です
ES2015より前は、JavaScriptではクラスの代わりにコンストラクター関数を使用していました。コンパイラはこのパターンをサポートしており、コンストラクター関数をES2015クラスと同等に理解しています。上記のプロパティ推論ルールは、まったく同じように機能します。
jsTry
functionC () {this.constructorOnly = 0;this.constructorUnknown =undefined ;}C .prototype .method = function () {this.Type 'boolean' is not assignable to type 'number'.2322Type 'boolean' is not assignable to type 'number'.constructorOnly = false;this.constructorUnknown = "plunkbat"; // OK, the type is string | undefined};
CommonJSモジュールがサポートされています
.js
ファイルでは、TypeScriptはCommonJSモジュール形式を理解します。 exports
およびmodule.exports
への代入は、エクスポート宣言として認識されます。同様に、require
関数呼び出しはモジュールインポートとして認識されます。例えば
js
// same as `import module "fs"`const fs = require("fs");// same as `export function readFile`module.exports.readFile = function (f) {return fs.readFileSync(f);};
JavaScriptのモジュールサポートは、TypeScriptのモジュールサポートよりも構文的に寛容です。代入と宣言のほとんどの組み合わせがサポートされています。
クラス、関数、およびオブジェクトリテラルは名前空間です
クラスは .js
ファイルの名前空間です。これは、たとえば、クラスをネストするために使用できます。
jsTry
classC {}C .D = class {};
また、ES2015 より前のコードでは、静的メソッドをシミュレートするために使用できます。
jsTry
functionOuter () {this.y = 2;}Outer .Inner = function () {this.yy = 2;};Outer .Inner ();
単純な名前空間を作成するために使用することもできます。
jsTry
varns = {};ns .C = class {};ns .func = function () {};ns ;
他のバリアントも許可されています。
jsTry
// IIFEvarns = (function (n ) {returnn || {};})();ns .CONST = 1;// defaulting to globalvarassign =assign ||function () {// code goes here};assign .extra = 1;
オブジェクトリテラルはオープンエンドです
.ts
ファイルでは、変数宣言を初期化するオブジェクトリテラルは、その型を宣言に与えます。元のリテラルで指定されていなかった新しいメンバーを追加することはできません。このルールは .js
ファイルでは緩和されます。オブジェクトリテラルには、元々定義されていなかったプロパティの追加と検索を許可するオープンエンドの型(インデックスシグネチャ)があります。例えば
jsTry
varobj = {a : 1 };obj .b = 2; // Allowed
オブジェクトリテラルは、クローズされたオブジェクトではなく、オープンマップとして扱えるように、インデックスシグネチャ [x:string]: any
を持つかのように動作します。
他の特別な JS チェック動作と同様に、この動作は変数の JSDoc 型を指定することで変更できます。例えば
jsTry
/** @type {{a: number}} */varobj = {a : 1 };Property 'b' does not exist on type '{ a: number; }'.2339Property 'b' does not exist on type '{ a: number; }'.obj .= 2; b
null、undefined、および空の配列の初期化子は、any型またはany[]型です
null または undefined で初期化された変数、パラメーター、またはプロパティは、厳密な null チェックがオンになっている場合でも、any 型になります。 [] で初期化された変数、パラメーター、またはプロパティは、厳密な null チェックがオンになっている場合でも、any[] 型になります。唯一の例外は、上記のように複数の初期化子を持つプロパティの場合です。
jsTry
functionFoo (i = null) {if (!i )i = 1;varj =undefined ;j = 2;this.l = [];}varfoo = newFoo ();foo .l .push (foo .i );foo .l .push ("end");
関数パラメーターはデフォルトでオプションです
ES2015 より前の JavaScript ではパラメーターのオプション性を指定する方法がないため、.js
ファイル内のすべての関数パラメーターはオプションと見なされます。宣言されたパラメーター数よりも少ない引数での呼び出しが許可されます。
関数を引数が多すぎる状態で呼び出すとエラーになることに注意することが重要です。
例えば
jsTry
functionbar (a ,b ) {console .log (a + " " +b );}bar (1); // OK, second argument considered optionalbar (1, 2);Expected 0-2 arguments, but got 3.2554Expected 0-2 arguments, but got 3.bar (1, 2,3 ); // Error, too many arguments
JSDoc アノテーション付きの関数はこの規則から除外されます。JSDoc のオプション パラメーター構文 ([
]
) を使用してオプション性を表現します。例:
jsTry
/*** @param {string} [somebody] - Somebody's name.*/functionsayHello (somebody ) {if (!somebody ) {somebody = "John Doe";}console .log ("Hello " +somebody );}sayHello ();
arguments
の使用から推論される可変長引数パラメーター宣言
本体に arguments
参照への参照がある関数は、暗黙的に可変長引数パラメーター (つまり (...arg: any[]) => any
) を持つと見なされます。引数の型を指定するには、JSDoc の可変長引数構文を使用します。
jsTry
/** @param {...number} args */functionsum (/* numbers */) {vartotal = 0;for (vari = 0;i <arguments .length ;i ++) {total +=arguments [i ];}returntotal ;}
指定されていない型パラメーターはデフォルトで any
になります
JavaScript にはジェネリック型パラメーターを指定するための自然な構文がないため、指定されていない型パラメーターはデフォルトで any
になります。
extends句内
たとえば、React.Component
は、2 つの型パラメーター Props
と State
を持つように定義されています。 .js
ファイルでは、extends 句でこれらを指定する正当な方法はありません。デフォルトでは、型引数は any
になります
js
import { Component } from "react";class MyComponent extends Component {render() {this.props.b; // Allowed, since this.props is of type any}}
JSDoc @augments
を使用して、型を明示的に指定します。例えば
js
import { Component } from "react";/*** @augments {Component<{a: number}, State>}*/class MyComponent extends Component {render() {this.props.b; // Error: b does not exist on {a:number}}}
JSDoc参照内
JSDoc で指定されていない型引数は、デフォルトで any になります
jsTry
/** @type{Array} */varx = [];x .push (1); // OKx .push ("string"); // OK, x is of type Array<any>/** @type{Array.<number>} */vary = [];y .push (1); // OKy .push ("string"); // Error, string is not assignable to number
関数呼び出し内
ジェネリック関数への呼び出しは、型パラメーターを推論するために引数を使用します。多くの場合、推論ソースの欠如が原因で、このプロセスは型の推論に失敗します。このような場合、型パラメーターはデフォルトで any
になります。例えば
js
var p = new Promise((resolve, reject) => {reject();});p; // Promise<any>;
JSDoc で利用できるすべての機能については、リファレンスを参照してください。