TypeScript: JavaScript から TypeScript へのスムーズな移行は、レゴの組み立てプロセスをアップグレードするようなものです。
「できることをして、持っているものを活用する」 – これは私のモットーの 1 つです。この文にも成長マインドセットの一端が反映されています。フロントエンドまたは JavaScript 開発者のほとんどは、すでに TypeScript への移行を開始しているか、完全に移行しています。しかし、概念を理解したり、JavaScript から TypeScript に考え方を切り替えるのがまだ難しい人もいるかもしれません。この問題を解決するために、私のお気に入りのツールの 1 つであるレゴを使用します。ここから始めましょう: 「JavaScript は、自由に構築できるレゴ ブロックの基本的なセットであると考えてください。TypeScript は同じブロックのセットですが、TypeScript についてさらに詳しく説明するには、次のようにします。」ここ、ここ、およびこのビデオを参照してください。このガイドは、JavaScript の各概念が TypeScript にどのように変換されるかを説明することを目的としています。概念をより簡単に理解できるように、レゴの例えを使用します。
変数スコープ は、プログラム内で変数にアクセスして使用できるコンテキストを指します。スコープには、ローカル スコープ と グローバル スコープ の 2 つの主なタイプがあります。関数の外で宣言された変数はグローバル スコープにあり、コード内のどこからでもアクセスおよび変更できることを意味します。一方、関数内で宣言された変数はローカル スコープにあり、その関数内でのみアクセスできます。 JavaScript は、var
、let
、および const
キーワードを使用して変数を宣言し、各キーワードはスコープに異なる影響を与えます。 let
と const
で宣言された変数はブロック スコープです。つまり、最も近い囲みブロック {}
内でのみアクセスできます。対照的に、var
は関数スコープなので、それが宣言されている関数全体で使用できます。変数のスコープを明確に理解すると、変数名の競合や JavaScript プログラムでの予期しない副作用などの問題を回避できます。
ホイスティングとは、コードが実行される (コンパイル段階) 前に、変数と関数の宣言をそれらを含むスコープの先頭に移動する行為です。これは、変数と関数を宣言する前に使用できることを意味します。関数宣言は完全にホイストされているため、コード内で定義される前でも呼び出すことができます。ただし、var
で宣言された変数はホイストされますが、初期値に初期化されないため、代入前にアクセスすると undefined
が返されます。 let
と const
で宣言された変数もホイストされますが初期化されず、宣言前にアクセスすると ReferenceError
になります。プロモーションを理解すると、開発者は変数と関数の宣言を正しく構築することでよくある落とし穴を回避できます。
スコープをさまざまなレゴの部屋として考えてください:
<code class="language-javascript">// 全局搭建房间 const globalBricks = "每个人都可以使用这些"; function buildSection() { // 个人搭建桌 var tableBricks = "仅供此搭建者使用"; if (true) { // 特定区域 let sectionBricks = "仅供此部分使用"; } }</code>
<code class="language-typescript">// 为我们的搭建房间添加类型安全 type BrickType = "regular" | "special" | "rare"; const globalBricks: BrickType = "regular"; function buildSection(): void { // TypeScript确保我们只使用有效的积木类型 const tableBricks: BrickType = "special"; if (true) { // TypeScript阻止在此块之外使用sectionBricks let sectionBricks: BrickType = "rare"; } } // 真实世界的例子:配置管理 interface AppConfig { readonly apiKey: string; environment: "dev" | "prod"; features: Set<string>; } const config: AppConfig = { apiKey: "secret", environment: "dev", features: new Set(["feature1", "feature2"]) };</code>
関数は、特定のタスクを実行するように設計された再利用可能なコード ブロックです。これにより、モジュール性とコード効率が向上します。これらは、function
キーワード、その後に名前、括弧 ()
、および中括弧 {}
で囲まれたコード ブロックを使用して定義できます。引数は括弧または中括弧内で関数に渡すことができ、関数が呼び出されたときに提供される値のプレースホルダーとして機能します。 JavaScript は、匿名関数 (名前のない) およびアロー関数 (よりクリーンな構文を提供する) もサポートしています。関数は、return
ステートメントを使用して値を返したり、値を返さない操作を実行したりできます。さらに、JavaScript の関数はファーストクラスのオブジェクトです。つまり、関数を変数に代入したり、引数として渡したり、他の関数から返すことができるため、関数型プログラミング パターンが可能になります。
クロージャは、関数がそのスコープ外で実行される場合でも、関数がその字句スコープを記憶してアクセスできるようにする強力な機能です。クロージャは、関数が関数内で定義され、外側の関数の変数を参照する場合に作成できます。外側の関数の実行が終了した後でも、内側の関数はこれらの変数にアクセスできます。この機能は、データのカプセル化と、イベント ハンドラーやコールバックなどの環境での状態の維持に役立ちます。クロージャはプライベート変数などのパターンをサポートしており、関数は実装の詳細を隠しながら特定の動作を公開できます。
<code class="language-javascript">function buildHouse(floors, color) { const foundation = "concrete"; return function addRoof(roofStyle) { return `${color} house with ${floors} floors and ${roofStyle} roof on ${foundation}`; }; }</code>
<code class="language-typescript">// 带有类型的基本函数 interface House { floors: number; color: string; roofStyle: string; foundation: string; } // 为我们的搭建者添加类型安全 function buildHouse( floors: number, color: string ): (roofStyle: string) => House { const foundation = "concrete"; return (roofStyle: string): House => ({ floors, color, roofStyle, foundation }); } // 真实世界的例子:组件工厂 interface ComponentProps { id: string; style?: React.CSSProperties; children?: React.ReactNode; } function createComponent<T extends ComponentProps>( baseProps: T ): (additionalProps: Partial<T>) => React.FC<T> { return (additionalProps) => { // 组件实现 return (props) => <div></div>; }; }</code>
JavaScript のオブジェクトは、関連するデータと機能のコンテナーとして機能する基本的なデータ構造です。これらはキーと値のペアで構成され、各キー (プロパティ) が値にマップされます。値は、関数 (メソッド) を含む任意の有効な JavaScript タイプにすることができます。オブジェクトはいくつかの方法で作成できます:
const obj = {}
new Object()
Object.create()
メソッドプロトタイプ システムは、JavaScript の組み込み継承メカニズムです。すべてのオブジェクトには、プロトタイプと呼ばれる別のオブジェクトへの内部リンクがあります。オブジェクトに存在しないプロパティにアクセスしようとすると、JavaScript はプロトタイプ チェーン内でそのプロパティを自動的に検索します。このオブジェクト チェーンは、null
プロトタイプ (通常は Object.prototype
) を持つオブジェクトに到達するまで続きます。プロトタイプを理解することは、以下にとって重要です。
オブジェクトとプロトタイプを次のように考えてください:
<code class="language-javascript">// 全局搭建房间 const globalBricks = "每个人都可以使用这些"; function buildSection() { // 个人搭建桌 var tableBricks = "仅供此搭建者使用"; if (true) { // 特定区域 let sectionBricks = "仅供此部分使用"; } }</code>
<code class="language-typescript">// 为我们的搭建房间添加类型安全 type BrickType = "regular" | "special" | "rare"; const globalBricks: BrickType = "regular"; function buildSection(): void { // TypeScript确保我们只使用有效的积木类型 const tableBricks: BrickType = "special"; if (true) { // TypeScript阻止在此块之外使用sectionBricks let sectionBricks: BrickType = "rare"; } } // 真实世界的例子:配置管理 interface AppConfig { readonly apiKey: string; environment: "dev" | "prod"; features: Set<string>; } const config: AppConfig = { apiKey: "secret", environment: "dev", features: new Set(["feature1", "feature2"]) };</code>
非同期関数は、非同期操作を処理するエレガントな方法を提供する JavaScript の特別な関数タイプです。 async
キーワードを使用して宣言すると、これらの関数は自動的に Promise を返し、本体での await
キーワードの使用が有効になります。 await
演算子は、Promise が解決されるか拒否されるまで関数の実行を一時停止し、非同期コードをより同期的で読みやすいスタイルで作成できるようにします。この構文はコールバックの複雑さを効果的に軽減し、ネストされた Promise チェーンの必要性を排除します。たとえば、async function fetchData() { const response = await fetch(url); }
では、関数は実行を続行する前に fetch
操作が完了するのを待機します。これにより、メイン スレッドがブロックされていない状態を維持しながら、コードの動作がより予測可能になります。このパターンは、開発者がパフォーマンスを犠牲にすることなく操作の順序を明確に表現するコードを作成できるため、相互に依存する複数の非同期操作を処理する場合に特に役立ちます。
Promise は、現在利用できるか、将来利用できるか、または決して利用できない可能性がある値を表します。これは、保留中、完了、拒否の 3 つの状態を持つオブジェクトです。非同期操作を処理するために使用されます。 Promise には、結果に基づいてアクションを連鎖させるための .then()
、.catch()
、.finally()
などのメソッドがあります。これにより、ネストされたコールバックの強力な代替手段となり、コードの可読性とエラー処理が向上します。
<code class="language-javascript">// 全局搭建房间 const globalBricks = "每个人都可以使用这些"; function buildSection() { // 个人搭建桌 var tableBricks = "仅供此搭建者使用"; if (true) { // 特定区域 let sectionBricks = "仅供此部分使用"; } }</code>
<code class="language-typescript">// 为我们的搭建房间添加类型安全 type BrickType = "regular" | "special" | "rare"; const globalBricks: BrickType = "regular"; function buildSection(): void { // TypeScript确保我们只使用有效的积木类型 const tableBricks: BrickType = "special"; if (true) { // TypeScript阻止在此块之外使用sectionBricks let sectionBricks: BrickType = "rare"; } } // 真实世界的例子:配置管理 interface AppConfig { readonly apiKey: string; environment: "dev" | "prod"; features: Set<string>; } const config: AppConfig = { apiKey: "secret", environment: "dev", features: new Set(["feature1", "feature2"]) };</code>
これは、配列から値を抽出したり、オブジェクトのプロパティをさまざまな変数に抽出したりする優れた方法です。配列の分割には角括弧 []
が使用され、オブジェクトの分割には中括弧 {}
が使用されます。この構文では、値を直接変数に展開することで重複コードの必要性が減り、複雑なデータ構造の処理が容易になります。たとえば、const [a, b] = [1, 2]
は a に 1、b に 2 を割り当てますが、const { name } = person
は person オブジェクトから name 属性を抽出します。
スプレッド演算子は 3 つのドット (...) で表されます。これにより、複数の要素またはキーと値のペアが必要な場合に、配列やオブジェクトなどの反復可能なオブジェクトを拡張できます。これを使用して、配列要素をコピー、結合、または関数の引数として渡すことができます。たとえば、const arr = [1, 2, ...anotherArray]
。
オプションのチェーンは ?.
で表されます。これは、プロパティが未定義または null の場合にエラーを発生させることなく、深くネストされたオブジェクト プロパティに安全にアクセスする方法を提供します。参照が null の場合、それは短絡され、ただちに未定義を返します。たとえば、user?.address?.street
は通りにアクセスする前にユーザーとアドレスが存在するかどうかを確認します。この構文により、実行時エラーが防止され、特にユーザー入力に依存する API やデータにおいて、ネストされたデータ構造の操作がよりクリーンになり、エラーが発生しにくくなります。
<code class="language-javascript">function buildHouse(floors, color) { const foundation = "concrete"; return function addRoof(roofStyle) { return `${color} house with ${floors} floors and ${roofStyle} roof on ${foundation}`; }; }</code>
<code class="language-typescript">// 带有类型的基本函数 interface House { floors: number; color: string; roofStyle: string; foundation: string; } // 为我们的搭建者添加类型安全 function buildHouse( floors: number, color: string ): (roofStyle: string) => House { const foundation = "concrete"; return (roofStyle: string): House => ({ floors, color, roofStyle, foundation }); } // 真实世界的例子:组件工厂 interface ComponentProps { id: string; style?: React.CSSProperties; children?: React.ReactNode; } function createComponent<T extends ComponentProps>( baseProps: T ): (additionalProps: Partial<T>) => React.FC<T> { return (additionalProps) => { // 组件实现 return (props) => <div></div>; }; }</code>
JavaScript から TypeScript への移行は、レゴの組み立てプロセスをアップグレードするようなものです:
JavaScript (基本構造):
TypeScript (専門的に構築された):
主要な移行ヒント:
覚えておいてください: TypeScript は、基本的な構築プロセスを変更するのではなく、JavaScript の知識に基づいて構築され、セキュリティと明確さを追加します。そうは言っても、私のアドバイスはやはり... まず JavaScript を学び、次に TypeScript を学ぶことです。
以上がTypeScript による構築: レゴベースのガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。