JavaScript TypeScript 変換ツール:PropTypesをインターフェースに
この JavaScript TypeScript 変換ツールは、移行の最初の退屈な作業を引き受けます。パーサーでコードを読み取り、ReactのPropTypesをインターフェースにし、デフォルト値から型を取り出し、推論できる型を追加して、整形済みのTypeScriptを返します。対象は1つのファイルやスニペットで、コードを実行することはなく、何もアップロードしません。推論できない部分はあなたに任せます。何が残るかは、以下の各項目で具体的に説明します。
JavaScript TypeScript 変換の使い方
- JavaScriptまたはJSXの欄にコードを貼り付けてください。貼り付けるまでは「ここにJavaScriptまたはJSXを貼り付けてください…」と表示されています。上限は500万文字です。
- 少し待ってください。入力や貼り付けの約0.35秒後に自動で変換されるため、押すボタンはありません。
- 結果は「TypeScript」の見出しの下に表示されます。コードにJSXが含まれる場合は「TypeScript (TSX)」です。読み取り専用で、色分けされて表示されます。
- コードの上の表示を確認してください。「インターフェースを2件書き出しました」「型注釈を11件追加しました」のように、行った内容が出ます。型が必要な箇所がなければ、「型が必要な箇所はなかったため、コードは整形のみ行いました。」と表示されます。
- クリップボードにコピーを選択してください。表示が「コピー完了」に変わります。
- コードの下の変換オプションには、ReactモードとStrictモードの2つのチェックボックスがあります。どちらかを変更すると、コードが再変換されます。
有効なJavaScriptでない場合は、「有効なJavaScriptではありません。N行目M列目に構文エラーがあります。」と表示され、問題の行と位置を示す印が付きます。すでにTypeScriptの構文を含むコードは無効として扱われます。貼り付けたコードだけが対象なので、コンポーネントやモジュール、スニペットに向いています。リポジトリ全体の変換には向きません。
具体例:PropTypesを使ったReactコンポーネント
入力は、PropTypesと型のないイベントハンドラーを持つ小さなカウンターです。変換するとインターフェースCounterPropsが書き出されます。labelはisRequiredがあるため必須で、startとonChangeは省略可能です。デフォルト値のn = 1はn: number = 1になり、buttonのonClickハンドラーではeにボタン要素用のReact.MouseEventが付きます。使われていないprop-typesのimportは削除され、JSXはPrettierで複数行に整形されます。表示は「インターフェースを1件書き出しました」と「型注釈を3件追加しました」です。
変わらない部分もあります。useState(start)はそのままです。値の使われ方から型を推測することはしないためです。
PropTypesをTypeScriptのインターフェースにする仕組み
Reactモードがオンのとき、コンポーネントのPropTypesから名前Propsというインターフェースを作り、コンポーネントの上に置いて、propsの型として使います。対象は、関数コンポーネント(宣言、アロー関数、memoで包んだもの)と、静的なpropTypesまたはFoo.propTypes = {...}の代入があるクラスです。.isRequiredが付いたpropは必須、それ以外には?が付きます。propの上のコメントはインターフェースに移ります。
stringとnumberは、そのままstringとnumberboolはbooleanfuncは、任意の引数を受け取る関数型arrayとobjectは、any[]と、キーがstringのRecordnodeとelementは、ReactNodeとReactElementarrayOf(T)とobjectOf(T)は、T[]と、値がTのRecordoneOf([...])は、'sm' | 'lg'のようなリテラルのユニオンoneOfType([...])は、列挙した型のユニオンshape({...})とexact({...})は、オブジェクト型instanceOf(Foo)はFoo
propTypesの文は削除され、ほかに使われていなければprop-typesのimportも削除されます。クラスコンポーネントでは、this.state = {...}からstateのインターフェースも作られます。PropTypesのないクラスでは、読み取ったthis.props.xからpropsのインターフェースが作られます。PropTypesのない関数コンポーネントにpropsのインターフェースが付くのは、Strictモードのときだけです。
PropTypesがなくても追加される型と、Strictモード
- デフォルト値:デフォルト値のある引数は、その値から型が付きます。
n = 5はn: number = 5、let x = 0はlet x: number = 0になります。 - 戻り値の型:すべての
returnが同じプリミティブ型(string、number、boolean)を返すとき、またはreturnがないときに追加されます。後者はvoid、async関数ならvoidのPromiseです。 - クラスのフィールド:クラス内のすべての
this.x = ...(何も継承しないクラスか、Reactコンポーネント)にプロパティ宣言が付きます。 - Reactのイベント:DOM要素のハンドラー引数には、
onChange、onClick、onSubmitなどに合わせてReact.ChangeEventのようなイベント型が付きます。 - ref:
useRef(null)は、付けた先のref={...}から要素の型を取ります。
Strictモードは初期設定でオフです。オンにすると、型を推論できない箇所がすべて見えるようになります。let x;はlet x: any;、const list = []はany[]になり、型のない引数には: anyが付きます。オフのときは、そうした箇所は型なしのままです。オンにすると、あとで直す箇所を検索しやすくなります。
変換しないもの、コメントの扱い、プライバシー
1つのコードだけを読み、推測はしません。次のケースはそのまま残るか、anyになります。
items.map((x) => ...)のように呼び出しへ直接渡すコールバックの引数:そのまま残します。受け取る関数側からTypeScriptが型を決められるようにするためです。- 別のファイルの型や、独自のPropTypesバリデーター:
anyになり、バリデーター自体は残りません。 forwardRefのコンポーネント:PropTypesには手を付けません。- JSDocの型コメント:読み取りません。
- 引数の名前や使われ方から型を推測すること:行いません。
- ファイルをまたぐ推論:行わないため、ファイルを1つずつ変換して確認してください。
- ReactモードをオフにしたときのPropTypes:そのまま残します。
出力は最初の一歩であり、完成した移行ではありません。プロジェクトに貼り付けてtscを実行し、anyを1つずつ手作業で絞り込んでください。ファイル名の変更は行わないため、コンポーネントは自分で.tsxとして保存してください。
コメントとレイアウトは保たれます。コードは@babel/parserで読み取り、型注釈は元のテキストへの編集として挿入し、その結果をPrettierが整形します。引用符のスタイル、セミコロン、インデント幅は維持されます。解析、編集、整形はすべてブラウザー内のWeb Workerで動き、コードがアップロードされることも実行されることもありません。変換の前にコードを整えたいときはコードフォーマッターを、圧縮や難読化されたスクリプトを先に読み解きたいときはJS難読化解除ツールを使ってください。
よくある質問
JavaScriptからTypeScriptへの変換はどうやりますか?
JavaScriptまたはJSXを「JavaScriptまたはJSX」の欄に貼り付けてください。約3分の1秒後に、「TypeScript」の見出しの下に結果が表示されます。コードにJSXが含まれる場合は「TypeScript (TSX)」です。変換ボタンはありません。結果は「クリップボードにコピー」で取り出せます。
ReactのPropTypesをTypeScriptのインターフェースにできますか?
はい。Reactモードがオンのとき、propTypesのオブジェクトはコンポーネント名にちなんだインターフェース(例:CounterProps)になります。isRequiredが付いたpropは必須で、ほかには疑問符が付きます。propTypesの文は削除され、ファイル内でほかに使われていなければprop-typesのimportも削除されます。関数コンポーネントと、静的なpropTypesを持つクラスに対応しています。
js ts 変換でJSXをTSXにするには?
JSXのコンポーネントを貼り付けてください。コードにJSXが含まれると、結果の見出しは「TypeScript (TSX)」になり、Reactモードが自動でオンになるため、propsにはインターフェース、ハンドラーにはイベント型が付きます。ファイル名の変更は行わないので、結果は拡張子.tsxで保存してください。JSX TSX 変換の手順は、貼り付けて、.tsxで保存するだけです。
ReactモードとStrictモードは何をしますか?
変換オプションにあるReactモードは、PropTypesをインターフェースにし、イベントハンドラー、props、フックに型を付けます。コードにJSX、react、prop-typesが含まれると初期設定でオンになり、オフにするとPropTypesはそのまま残ります。Strictモードは初期設定でオフで、型を推論できない箇所に、省略せず明示的なanyを書き込みます。
出力にanyが残るのはなぜですか?
型は、コードそのものから読み取れる場合にだけ書き込まれます。独自のPropTypesバリデーターや別ファイルからインポートした型はanyになり、Strictモードでは型のない変数や引数に明示的なanyが付きます。出力は最初の一歩です。tscで確認して、anyを本当の型に置き換えてください。
コールバックの引数に型が付かないのはなぜですか?
items.map((x) => x.id)のxのように、呼び出しへ直接渡した引数は、意図的にそのまま残します。コールバックを受け取る関数側から、TypeScriptが型を決められるようにするためです。
コメントや書式は保たれますか?
コメントは保たれます。コードを作り直すのではなく、型注釈を元のテキストへの編集として挿入するためです。その後Prettierで整形し、引用符のスタイル、セミコロン、インデント幅は維持されますが、長い行は折り返される場合があります。PropTypesの項目の上にあるコメントは、対応するインターフェースのプロパティへ移ります。
コードはアップロードされたり実行されたりしますか?
いいえ。コードはブラウザー内のWeb Workerで解析・書き換えされ、サーバーには送られません。実行もされないため、副作用のあるスクリプトを貼り付けても安全です。構文エラーがあると、行番号と列番号が表示されます。上限は500万文字です。
おすすめ
-
Amazonベーシック 6in1 USB-CハブノートPCに足りないHDMI・SD・USBを1台にまとめて、移行作業の環境を一度つなぐだけにできます。
-
ASUS ZenScreen 15.6型 モバイルモニター元の.jsをこの画面に、変換後の.tsを隣に並べて、型を一つずつ見比べられます。
-
ロジクール Alto Keys K98M メカニカルキーボード打鍵感の良いメカニカルキーボードで、何百ファイルもの型付け作業を快適に続けられます。
無料でツールを続ける支えになります。✨
画像はイメージです。 Amazonのアソシエイトとして、Capsule Toolsは適格販売により収入を得ています。