バックグラウンド
□ TypeScript は、JavaScript で開発された大規模プロジェクトから生まれました。JavaScript 言語自体の制限により、大規模なプロジェクト開発を適切に実行して維持することが困難であるため、Microsoft は大規模プロジェクトの開発に適した TypeScript を開発しました。
□ TypeScript は Microsoft が開発したオープンソースのプログラミング言語で、JavaScript をベースに静的な型定義を追加して構築されています。TypeScript は、TypeScript コンパイラーまたは Babel を通じて JavaScript コードに変換され、任意のブラウザーおよび任意のオペレーティング システムで実行できます。
□ 2012 年 10 月、Microsoft は TypeScript の最初の公開バージョンをリリースしました。2013 年 6 月 19 日、Microsoft はプレビュー バージョンを経て、TypeScript の正式版をリリースしました。
□ TypeScript の作者は、C# のチーフ アーキテクトでもある Anders Hailsberg です。
特性
TypeScript は、JavaScript に機能を追加する言語拡張機能であり、JavaScript のスーパーセットです。
型の注釈
□ ブール値
let isDone: boolean = false;
□数字
let decLiteral: number = 6;
let hexLiteral: number = 0xf00d;
let binaryLiteral: number = 0b1010;
□文字列
let name: string = "bob";
□配列
let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];
□タプル
let x: [string, number] = ['hello', 10];
□ 列挙
enum Color {Red = 1, Green = 2, Blue = 4}
let c: Color = Color.Green;
let colorName: string = Color[2];
alert(colorName);
□ 任意の値
let notSure: any = 4;
notSure = true;
let list: any[] = [1, true, "free"];
list[1] = 100;
□ Null値
function func(): void {
alert("hello world");
}
// void类型的变量只能被赋值成undefined和null
let unusable: void = undefined;
□ null および未定義
let a: undefined = undefined;
let b: null = null;
デフォルトでは、null と unknown はすべての型のサブタイプです。つまり、number 型の変数に null と unknown を割り当てることができます。ただし、 --strictNullChecks フラグを指定すると、null と unknown は void とそれ自体にのみ割り当てることができるため、多くの一般的な問題が回避されます。
□ ジョイントタイプ
共用体タイプは、値が複数のタイプのいずれかであることを示します。各型は垂直バー (|) で区切られているため、number | string | boolean は、値が数値、文字列、またはブール値であることを意味します。
値が共用体型の場合、その共用体型のすべての型に共通するメンバーのみにアクセスできます。
interface Bird {
fly(); layEggs();
}
interface Fish {
swim(); layEggs();
}
function getSmallPet(): Fish | Bird {}
let pet = getSmallPet();
pet.layEggs();
// 不是共有成员,会报错
pet.swim();
□型変換(型アサーション)
方法 1:
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
方法 2:
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
どちらの形式も同等であり、どちらを使用するかは主に個人的な好みの問題です。TypeScript で JSX を使用する場合、as 構文のみが許可されます。
インターフェース
□ インターフェース定義
interface ConfigOptions {
// 必须带的属性
color: string;
// 可选属性
width?: number;
// 只读属性
readonly x: number;
// 函数类型
setTime(d: Date);
}
interface ConfigOptions2 {
color: string;
// 字符串索引签名(可以有任意数量的其他属性)
[propName: string]: any;
}
interface StringArray {
// 数字索引签名
[index: number]: string;
}
let myArray: StringArray;
myArray = ["Bob", "Fred"];
let myStr: string = myArray[0];
□ インターフェースの使用方法
function create(config: ConfigOptions) {
}
create({ colour: "red", width: 100, x: 2 });
create({ colour: "red", width: 100, x: 2 } as ConfigOptions);
□インターフェースを継承
interface Shape {
color: string;
}
interface Square extends Shape {
len: number;
}
親切
□ クラス定義
class Greeter {
greeting: string;
// 只读属性必须在声明时或构造函数里被初始化
readonly name: string;
readonly numberOfLegs: number = 8;
constructor(message: string, name: string) {
this.greeting = message;
this.name = name;
}
greet() {
return "Hello, " + this.greeting;
}
}
□パラメータのプロパティ
パラメーターのプロパティは、コンストラクターのパラメーターにアクセス修飾子を追加することによって宣言されます。パラメーター プロパティを private で修飾すると、プライベート メンバーが宣言および初期化されます。これは、public および protected の場合も同様です。
class Animal {
constructor(private name: string) { }
move(distanceInMeters: number) {
console.log(${this.name} moved ${distanceInMeters}m.);
}
}
□ アクセサ
ゲッター/セッターを介してオブジェクト メンバーへのアクセスを傍受する
class Employee {
private _fullName: string;
get fullName(): string {
return this._fullName;
}
set fullName(newName: string) {
this._fullName = newName;
}
}
let employee = new Employee();
employee.fullName = "Bob Smith";
alert(employee.fullName);
□ クラスの継承
class Animal {
move(distanceInMeters: number = 0) {
console.log(Animal moved ${distanceInMeters}m.);
}
}
class Dog extends Animal {
bark() {
console.log('Woof! Woof!');
}
}
let dog = new Dog();
dog.bark();
dog.move(10);
□ 抽象クラス
abstract class Department {
constructor(public name: string) {
}
abstract printMeeting(): void; // 必须在派生类中实现
}
class AccountingDepartment extends Department {
constructor() {
super('Accounting and Auditing');
}
printMeeting(): void {
console.log('The Accounting Department meets each Monday at 10am.');
}
}
モジュール
□ ECMAScript 2015 から JavaScript にモジュールの概念が導入され、TypeScript もこの概念を使用します。
□ モジュールは、グローバル スコープではなく、独自のスコープで実行されます。これは、モジュール内で定義された変数、関数、クラスなどは、明示的にエクスポートしない限り、モジュールの外部には表示されないことを意味します。逆に、他のモジュールによってエクスポートされた変数、関数、クラス、インターフェイスなどを使用したい場合は、それらをインポートする必要があり、インポートを使用できます。
□ モジュールは自己宣言型であり、2 つのモジュール間の関係は、ファイル レベルでインポートとエクスポートを使用して確立されます。
export
export as
export default
import
import as
import default
ジェネリック
□ 渡された値を返す関数 echo を設計します。
function echo(arg: number): number {
return arg;
}
function echo(arg: any): any {
return arg;
}
function echo<T>(arg: T): T {
return arg;
}
let output = echo<string>("myString");
let output = echo("myString");
□ ジェネリックを使用してジェネリック関数を作成する場合、コンパイラは関数本体でこのジェネリック型を正しく使用することを要求します。つまり、これらのパラメータを任意のタイプまたはすべてのタイプとして扱う必要があります。
function echo<T>(arg: T): T {
console.log(arg.length);
return arg;
}
function echo<T>(arg: T[]): T[] {
console.log(arg.length);
return arg;
}
let myEcho: <T>(arg: T) => T = echo;
□ 汎用クラス
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
let stringNumeric = new GenericNumber<string>();
stringNumeric.zeroValue = "hello";
□ 一般的な制約
interface Lengthwise {
length: number;
}
function echo<T extends Lengthwise>(arg: T): T {
console.log(arg.length);
return arg;
}
// 约束不通过
echo(3);
// 约束通过
echo({length: 10, value: 3});
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
let x = { a: 1, b: 2, c: 3, d: 4 };
// 约束通过
getProperty(x, "a");
// 约束不通过
getProperty(x, "m");
□ クラス型(ジェネリクスを使用してファクトリ関数を作成する場合、コンストラクタのクラス型を参照する必要があります)
class Animal {
numLegs: number;
}
class Bee extends Animal {
name1: string;
}
class Lion extends Animal {
name2: string;
}
function createInstance<A extends Animal>(c: new () => A): A {
return new c();
}
alert(createInstance(Lion).name2)