| ページ一覧 | ブログ | twitter |  書式 | 書式(表) |

MyMemoWiki

差分

ナビゲーションに移動 検索に移動
14,292 バイト追加 、 2022年9月13日 (火) 11:59
| [[Node.js]] | [[Angular]] | [[Google Cloud Platform]] | [https://www.typea.info/blog/index.php/category/typescript/ ブログカテゴリ(TypeScript)] | [[JavaScript]] |
 
{{amazon|4873119049}}
 
==[[TypeScript]]==
[[Node.js]] | [[Angular]] | [[Google Cloud Platform]] |
{{amazon|B0733113NK}}
{{amazon|4873119049}}
*https://www.typescriptlang.org/docs/home.html
===準備===
----
====install====
----
[[npm]]
 
> [[npm]] install -g typescirpt
====init====
----
=====tsconfig.json の生成=====
----
> tsc --init
====[[Visual Studio Code]] タスク====
----
F1 - task run - build tsconfig.json
 
====Proejctテンプレート====
----
*https://www.typescriptlang.org/docs/bootstrap
*TypeScriptはJavaScriptのスーパーセットであるため、デフォルトのテンプレートはありません -
*代わりに、他のプロジェクトが独自のコンテキストを持つ独自のTypeScriptブートストラップ・テンプレートを用意しています。
====Playground====
----
*動作確認や、どのような[[Java]]scriptに変換されるか確認
*https://www.typescriptlang.org/play/
[[File:1217_ts_playground.jpg]]
 
==モジュール==
*CommonJSのモジュール標準requreでは、同期的呼び出しになる、静的に解析可能でない場合がある。
*module.exportsもrequire もコードのどこでも使用可能で任意の文字列、式を含むことができる。
var hogeModule = require('hogeModule');
module.exports.hoge = function() {}
*ES2015(JavaScript 6thエディション)では静的に解決可能な簡潔な公文を導入
*TypeScriptでの使用標準
import hoge from 'hogeModule';
export function hoge() {}
===インポート・エクスポート===
*[https://qiita.com/rooooomania/items/4c999d93ae745e9d8657 CommonJS と ES6の import/export で迷うなら]
 
====ES2015のimport/export構文を使用すべき====
*a.ts
export function foo() {}
export function bar() {}
*b.ts
import { foo, bar } from './a';
foo();
export let result = bar();
====ES2015ではデフォルトエクスポートをサポート====
*c.ts
export default function hoge(param: number) {}
*d.ts
import hoge from './c';
hoge(12);
====ワイルドカードで全てをインポート可能====
*e.ts
import * as a from './a';
a.foo();
a.bar();
====モジュールから再エクスポート可能====
*f.ts
export * from './a';
export { result } from './b';
export hoge from './c';
====TypeScriptでは型やインターフェースもエクスポート可能====
*g.ts
export let X = 3;
export type Y = { y: string };
 
===名前空間===
<q>TypeScriptで名前空間はサポートされているが、カプセル化のための望ましい方法ではない。名前空間とモジュール化のどちらを選択するか確信を持てない場合、モジュール化を選択する。JavaScriptの標準により従うことになり、依存関係がより明示的になる。特に中、大規模プロジェクト</q>
 
*namespace ブロックで定義
*exportで外側からアクセス可能なことを明示
*完全修飾名で呼び出す
namespace NameA {
export class Foo {
name() {
console.log("NameA.Foo");
}
}
export function bar(){
console.log("NameA.bar()");
}
}
let foo = new NameA.Foo();
foo.name();
NameA.bar();
====名前空間のネスト====
namespace NameB {
export namespace NameC {
export function bar(){
console.log("NameB.NameC.bar()");
}
}
}
NameB.NameC.bar();
==変数・型==
!型
!説明
|-
|any
|任意、型がわからない場合。型チェックされずなんでもできてしまうため、できれば避ける。
|-
|unknown
|any同様任意の型をあらわすが、前もって型がわからない場合、anyではなくこちらの利用を推奨
|-
|number
|数値
|-
|bigint
|まるめ誤差なく大きな整数を扱うことができる(プラットフォームでサポートされているか確認が必要) let bi = 123n
|-
|string
|symbol
|シンボル
|-
|any
|任意
|-
|object
|オブジェクト
|-
|T[]
|配列 number[],string[]
|}
 
====unknown型====
*値の比較、否定、typeof,instanceofが使用可能。以下のように利用する
let foo: unknown;
foo = 1;
// let bar = foo + 2; // unknown のためエラー
if (typeof foo == 'number') {
let bar = foo + 2; // OK
console.log(bar);
}
====undefinedも許可====
*string もしくは undefined
}
var h: hoge = {aa:'aaa'};
 
===演算子===
*基本的に[[JavaScript]]と同じ
*https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators
 
{|class="wikitable"
!演算子
!説明
|-
|??
|[https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator Null合体] 左辺が null または undefined の場合に右の値を返し、それ以外の場合に左の値
|-
|
|
|-
|
|
|-
|
|
|-
|
|
|-
|}
===文字列リテラル===
===型アサーション===
*====キャスト====
function show(message: string) {
console.log(`${message}`);
}
}
 
===コレクション/インターフェース===
*配列
P
===タプル===
*配列のサブタイプ
*固定長の配列を型づけ
let tpl: [string, number, boolean] = ['Yagi', 46, true];
console.log(`name:${tpl[0]} age:${tpl[1]} marriged:${tpl[2]}`);
 ===合併型(共用型)と交差型===*型の合併と交差を表現する特別な演算子が用意されている。*合併 | と交差 &*型エイリアスの例 type Sales = { dept: string, product: string}; type Engineer = { dept: string, project: string }; type SalesOrEngineewOrBoth = Sales | Engineer; // 合併 type DeptPerson = Sales & Engineer; // 交差 *合併型(共用型)使用例
let data: string | boolean;
data = 'foo';// OK
let datas: (boolean | number)[] = [true, false, 1, 0];
 
===型エイリアス===
*型の別名を定義できる*ブロックスコープ // type Age = number; let myage: Age = 48; *主にタプル、共用型に別名を付与。インターフェースでできる場合に使用しないほうがよい
type ProfileTuple = [string, number, boolean];
let me = ['yagi', 46, true];
console.log(`name:${me[0]} age:${me[1]} marriged:${me[2]}`);
 
===文字列リテラル===
type Season = 'spring' | 'summer' | 'autumn' | 'winter';
}
}
 
===keyof演算子===
 
==関数==
*function命令
*関数リテラル(型明示)
*アロー関数(ラムダ式)
[[Category:ラムダ]]
 
function squire(x: number, y: number) :number {
return x * y;
}
}
===ユーザー定義型ガード===
*typeaof/instanceof は組み込みの型を絞り込むための機能
*is 演算子を使用して独自に定義可能
function hoge(val:string | number) {
if (isString(val)) {
console.log(val.toUpperCase());
} else {
console.log(val);
}
}
// boolean を返す関数の場合、型の絞り込みを行うことができる
function isString(val: unknown): val is string {
return typeof val === 'string';
}
hoge(1);
hoge('a');
*結果
1
A
===関数のオーバーロード2===
constructor(public name: string, private _age: number)
}
====アクセス修飾子====
{|class="wikitable"
!修飾子
!説明
|-
|public
|どこからでもアクセス可能。デフォルト。
|-
|protected
|このクラスと、サブプラスのインスタンスからアクセス可能。
|-
|private
|このクラスのインスタンスのみからアクセス可能
|}
===名前空間===
*namespace ブロックで定義
*exportで外側からアクセス可能なことを明示
*完全修飾名で呼び出す
namespace NameA {
export class Foo {
name() {
console.log("NameA.Foo");
}
}
export function bar(){
console.log("NameA.bar()");
}
}
let foo = new NameA.Foo();
foo.name();
NameA.bar();
====名前空間のネスト====
namespace NameB {
export namespace NameC {
export function bar(){
console.log("NameB.NameC.bar()");
}
}
}
NameB.NameC.bar();
===継承===
class Guiter {
(new Lespaul()).print();
===抽象クラス===
*直接インスタンス化しようとするとエラー
// 抽象クラス
abstract class Viecle {
}
(new Premacy()).printDisplacement();
 
===インターフェース===
*型エイリアスと同様、インターフェースは型に名前をつけるための方法
**ほぼ同じだが、細かな差異もある。
*インラインで型を定義する必要がなくなる。
 
interface Color {
// メソッドはすべて抽象メソッド
}
console.log((new [[R]]ed()).get[[R]]GB());
 
====型とインターフェースの違い====
*型は右辺に任意の値をおけるがインターフェースはそうではない。
*以下のようなコードはインターフェースに書き換えられない
type A = number;
type B = A | string;
*インターフェースを拡張する場合、拡張元が拡張先に適用できるかチェックする。型エイリアスの場合拡張元と先を結合するために最善を尽くす
*同じスコープに同じ名前のインターフェースが複数存在する場合、自動的にマージされる。
 
===super===
*親クラスのメソッドを呼び出すことができる。super.hoge();
*コンストラクターとして呼び出す。super();
===構造的部分型(Structual subtyping)===
====ジェネリック型の定義 ====
*StringBuilder型は、上記で定義参照
*型引数に制約を付与する場合、extends を使用する。
*使用しなければ、あらゆる型を渡すことができる
 
class XmlBuilder extends StringBuilder {
constructor(protected _value: string){
rep.report();
=====出力例=====
&lt;values&gt;&lt;value&gt;this is lesson.&lt;/value&gt;&lt;value&gt;of [[TypeScript]].&lt;/value&gt;&lt;/values&gt;
====ジェネリックメソッド====
===サンプル===
{{ref app.ts}}
 
==非同期プログラミングと並行・並列処理==
===ObservableとPromise===
*https://angular.jp/guide/comparing-observables
====比較====
*Observable は宣言型で、購読するまで処理が開始されない。Promise は作成時に直ちに実行される。
**結果が必要なときにいつでも実行できるレシピを定義するために、Observable が役立つ。
*Observable は多くの値を提供します。Promise は1つです。
**時間の経過とともに複数の値を取得するのには Observable が有効
*Observable は、連鎖とサブスクリプションを区別します。Promise は .then() 句しかありません。
**Observableは、作業を実行させることなく、システムの他の部分で使用される複雑な変換レシピを作成するのに便利
*Observable の subscribe() はエラーを処理します。Promise は子の Promise にエラーをプッシュします。
**Observable は集中管理され、予測可能なエラー処理に役立
 
===Observable===
*RxJsライブラリ
*https://angular.jp/guide/rx-library
 
リアクティブプログラミングは、データストリームと変更の伝播に関する非同期プログラミングのパラダイムです。
RxJS (Reactive Extensions for JavaScript) は、非同期またはコールバックベースのコード (RxJS Docs) の作成を容易にする
observables を使用したリアクティブプログラミング用のライブラリ
 
*非同期処理の既存のコードを observables に変換する
*ストリーム内の値を反復処理する
*異なる型への値のマッピング
*ストリームのフィルタリング
*複数のストリームの作成
 
====Observable 作成関数====
ベント、タイマー、promise などから observables を作成するプロセスを簡素化
====promise から observable を作成====
import { from } from 'rxjs';
// promise から Observable を作成
const data = from(fetch('/api/endpoint'));
// 非同期の結果の購読を開始
data.subscribe({
next(response) { console.log(response); },
error(err) { console.error('Error: ' + err); },
complete() { console.log('Completed'); }
});
 
====カウンターから observable を作成する====
import { interval } from 'rxjs';
// 一定間隔でで値を発行するObservable を作成
const secondsCounter = interval(1000);
// 発行される値の購読を開始
secondsCounter.subscribe(n =>
console.log(`It's been ${n} seconds since subscribing!`));
 
====イベントから observable を作成する====
import { fromEvent } from 'rxjs';
const el = document.getElementById('my-element');
// マウスの移動を発行する Observable の作成
const mouseMoves = fromEvent(el, 'mousemove');
// マウス移動イベントを購読開始
const subscription = mouseMoves.subscribe((evt: MouseEvent) => {
console.log(`Coords: ${evt.clientX} X ${evt.clientY}`);
// スクリーンの左端をマウスが越えたら購読中止
if (evt.clientX < 40 && evt.clientY < 40) {
subscription.unsubscribe();
}
});
 
====AJAX リクエストから observable を作成====
 
import { ajax } from 'rxjs/ajax';
// AJAXリクエストを生成する Observable の作成
const apiData = ajax('/api/data');
// リクエストの生成を購読
apiData.subscribe(res => console.log(res.status, res.response));
 
===Promise===
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
*非同期の作業を抽象化して、それらを組み立てたり順番に並べる方法
import { isNumber } from "util";
function getPromise(waittime:string): Promise<string> {
return new Promise<string>((resolve, reject) => {
if (isNaN(Number(waittime)) ) {
reject("error");
} else {
const wt = parseInt(waittime);
setTimeout(() => {
resolve(`WAIT ${wt}`);
}, wt);
}
});
}
function usePromise() {
getPromise("2000")
.then((v) => {
console.log(v);
})
.catch((e) => {
console.log(e);
});
getPromise("aaaaa")
.then((v) => {
console.log(v);
})
.catch((e) => {
console.log(e);
});
}
usePromise();
*結果
非同期で呼び出すため、呼び出し結果と出力順序が入れ替わる
error
WAIT 2000
 
===async , await===
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
*Promiseはとてもポピュラーなパターンなので、JavaScript(TypeScript)では独自の構文が用意されている。
*await は .then に対するシンタックスシュガーと言える
*await を使ってPromiseを待機する場合、async ブロックの中で行う
*ラムダの場合 hoge(async ()=> {})
import { isNumber } from "util";
function getPromise(waittime:string): Promise<string> {
return new Promise<string>((resolve, reject) => {
if (isNaN(Number(waittime)) ) {
reject("error");
} else {
const wt = parseInt(waittime);
setTimeout(() => {
resolve(`WAIT ${wt}`);
}, wt);
}
});
}
async function usePromise() {
try {
let result = await getPromise("2000")
console.log(result);
let result2 = await getPromise("aaaa")
console.log(result2);
} catch(e) {
console.log(e);
}
}
usePromise();
*結果
await で同期されるため、呼び出し順に出力される
WAIT 2000
error
 
===非同期ストリーム===
*一般的には、イベントエミッター(Node.jsでは、EventEmitter)、リアクティブプログラミングライブラリー([https://www.npmjs.com/package/rxjs RxJS]、[https://github.com/mostjs/core MostJS] など)を利用する
*2つの違いはコールバックとPromiseに似ている。イベントエミッターは軽量、迅速であり、リアクティブプログラミングは強力でイベントストリームを組み立てたり並べたりが可能
===マルチスレッディング===
*上記までは非同期処理
*マルチスレッドによる並列処理を行う
*[[TypeScript 並列処理]]
 
==Node.jsを使う==
[[Node.js]]
 
*https://ics.media/entry/4682/
*[https://www.typea.info/blog/index.php/2020/07/23/typescript_node_environment/ ローカルにTypeScriptの動作確認環境をNode.jsで作成]
===環境構築===
*作業ディレクトリで実行
$ npm init -y
Wrote to /Users/hirotoyagi/Workspaces/Node/sample/package.json:
{
"name": "sample",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
*package.jsonを編集
"scripts": {
"build": "tsc",
"watch": "tsc --watch"
},
*TypeScriptのインストールと確認
$ npm install --save-dev typescript
$ node_modules/.bin/tsc --version
Version 3.9.7
*初期化
$ node_modules/.bin/tsc --init
message TS6071: Successfully created a tsconfig.json file.
*[[Node.js]]の型定義をインストール
$ npm install --save @types/node
*tsをTypeScriptで記述しjsにコンパイル
app.ts
console.log("test");
 
$ npm run build
*app.js が生成されるので、Nodeで実行
app.js
"use strict";
console.log("test");
 
$ node app
==[[Tips]]==
====作成====
&gt; typedoc --out ./docs/ ./src/ --module commonjs
 
===ASP.NET===
*[https://docs.microsoft.com/ja-jp/visualstudio/javascript/tutorial-aspnet-with-typescript?view=vs-2019 TypeScript を使用した ASP.NET Core アプリの作成]
 
===GAE===
*https://cloud.google.com/appengine/docs/standard/nodejs/running-custom-build-step?hl=ja
[[Google App Engine]]
 
{{amazon|B0733113NK}}
===配列===
====[[JavaScript Array|配列でなければ配列に、配列ならそのまま(もしくは追加)]]====
*[[JavaScript Array|配列でなければ配列に、配列ならそのまま(もしくは追加)]]
 
[[category:プログラミング言語]]

案内メニュー