前回
今回で最後。
名前空間
コードをグループ化できるやつで、名前の衝突を防げる。これも C# とほぼ同じなので、大丈夫だと思う。
namespace A { export function func{ } } namespace B { export function func{ } } // 同じメソッド名でも名前空間によって識別可能 let val1 = A.func; let val1 = B.func;
これを意識できれば、たとえ関数名が衝突しても区別可能。
namespace Greetings { export function returnGreeting (greeting: string) { console.log(`The message from namespace Greetings is ${greeting}.`); } } namespace GreetingsWithLength { export function returnGreeting (greeting: string) { let greetingLength = getLength(greeting); console.log(`The message from namespace GreetingsWithLength is ${greeting}. It is ${greetingLength} characters long.`); } function getLength(message: string): number { return message.length; } } Greetings.returnGreeting("Hello!"); GreetingsWithLength.returnGreeting("Hello, World!");
実行結果
The message from namespace Greetings is Hello!. The message from namespace GreetingsWithLength is Hello, World!. It is 13 characters long.
名前空間のネスト
名前空間の中に名前空間を含めることができる。これも C# と同じ。使用したいメソッドがあるところまでドット演算子で参照していけばいい。
namespace AllGreetings { export namespace Greetings { export function returnGreeting (greeting: string) { console.log(`The message from namespace Greetings is ${greeting}.`); } } export namespace GreetingsWithLength { export function returnGreeting (greeting: string) { let greetingLength = getLength(greeting); console.log(`The message from namespace GreetingsWithLength is ${greeting}. It is ${greetingLength} characters long.`); } function getLength(message: string): number { return message.length } } }
名前空間エイリアス
入れ子になっていると参照するために色々書かなければいけないので、面倒。そんなときは途中までのネストをまとめて変数として扱えば良い。
import greet = AllGreetings.Greetings; greet.returnGreeting("Hello!");
マルチファイル名前空間
複数のファイル間で名前空間を共有することで、拡張ができる。ファイルに reference
タグをつけてあげると、コンパイラに必要な名前空間を教えることができる。
// interfaces.ts namespace Interfaces { } // function.ts /// <reference path="interfaces.ts" /> namespace Functions { export function func{ } } // main.ts /// <reference path="interfaces.ts" /> /// <reference path="functions.ts" /> let x = Functions.func();
課題
これで最後の課題。
namespace Loans { export interface Loan { principle: number, interestRate: number } export interface ConventionalLoan extends Loan { months: number } } namespace LoanPrograms { export function calculateInterestOnlyLoanPayment(loanTerms: Loans.Loan): string { let payment: number; payment = loanTerms.principle * calculateInterestRate(loanTerms.interestRate); return 'The interest only loan payment is ' + payment.toFixed(2); } export function calculateConventionalLoanPayment(loanTerms: Loans.ConventionalLoan): string { let interest: number = calculateInterestRate(loanTerms.interestRate); let payment: number; payment = loanTerms.principle * interest / (1 - (Math.pow(1/(1 + interest), loanTerms.months))); return 'The conventional loan payment is ' + payment.toFixed(2); } function calculateInterestRate (interestRate: number): number { let interest: number = interestRate / 1200; return interest } } let interestOnlyPayment = LoanPrograms.calculateInterestOnlyLoanPayment({principle: 30000, interestRate: 5}); let conventionalLoanPayment = LoanPrograms.calculateConventionalLoanPayment({principle: 30000, interestRate: 5, months: 180}); console.log(interestOnlyPayment); console.log(conventionalLoanPayment);
名前空間ごとに機能を分けて、それを参照して呼び出すことができた。このプログラムはローンをシミュレーションするやつで以前もやったため、実行結果は省略。
完走した感想
このモジュールパス、結構な量なので時間がかかります。目安は約6時間30分とありますが、実際には8時間くらいやっていたと思います。docs だけでは理解できないところがあったので、色々調べたり、演習をやったりしていたので。
TypeScript を始めて1週間くらいしか経過していませんが、他人の書いたコードがなんとなく読めるようになってきました。というより、処理を追えるようになったと思います。
で、当初の目的は Fluent UI を扱えるようになることでした。しかし、そのためにはまずは TypeScript と React をやらないといけないわけだったのですが、ついに両方のラーニングパスを終えました。ようやく Fluent UI に触れられます。
初めて Fluent UI を導入したときは「なんやこれ?さっぱりやんけ」となっていたのですが、この約10日程度でどこまでできるようになったのか、色々試してみたいと思います。
イベントのお知らせ
2022年4月24日(日)に MS Tech Camp #14 を開催します。今回は私「たくのろじぃ」主催で、Blazor を使ったポートフォリオサイト製作と Azure Static Web Apps へのデプロイをやります。 興味がある方は(社会人、学生問わず)ぜひご参加ください! Youtube での配信ですので、休日はごろごろしながらご覧いただければと思います。もちろん、一緒にやっていただいても結構です!