前端學習-TypeScript菜鳥教程-002-TypeScript基礎知識

ayubene發表於2024-03-27

菜鳥教程連結

基本是閱讀教程,記筆記大部分為直接複製

基礎型別

  • any,number,string,boolean,陣列(如let x:number[] = [1,2]let x:Array<number> = [1,2]),元組(let x: [string, number])
  • enum
enum Color {Red, Green, Blue};
let c: Color = Color.Blue;
  • void : 用於標識方法返回值的型別,表示該方法沒有返回值。
  • null,undefined
  • never
    never 是其它型別(包括 null 和 undefined)的子型別,代表從不會出現的值。這意味著宣告為 never 型別的變數只能被 never 型別所賦值,在函式中它通常表現為丟擲異常或無法執行到終止點(例如無限迴圈)
let x: never;
let y: number;

// 編譯錯誤,數字型別不能轉為 never 型別
x = 123;

// 執行正確,never 型別可以賦值給 never型別
x = (()=>{ throw new Error('exception')})();

// 執行正確,never 型別可以賦值給 數字型別
y = (()=>{ throw new Error('exception')})();

// 返回值為 never 的函式可以是丟擲異常的情況
function error(message: string): never {
    throw new Error(message);
}

// 返回值為 never 的函式可以是無法被執行到的終止點的情況
function loop(): never {
    while (true) {}
}

變數宣告

  • TypeScript 遵循強型別,如果將不同的型別賦值給變數會編譯錯誤
let num:number = "hello"  
  • 型別斷言(Type Assertion)用來手動指定一個值的型別,即允許變數從一種型別更改為另一種型別。
var str = '1' 
// var str2:number = <number> <any> str   //str、str2 是 string 型別
var str2:number = <number> (str as any)   //str、str2 是 string 型別
console.log(str2)

函式

  • 函式返回值
function function_name():return_type { 
    // 語句
    return value; 
}
  • 帶參函式
function add(x: number, y: number): number {
    return x + y;
}
console.log(add(1,2))
  • 可選引數和預設引數
function buildName(firstName: string, lastName?: string = 'bene') {
    if (lastName)
        return firstName + " " + lastName;
    else
        return firstName;
}
 
let result1 = buildName("Bob");  // 正確 Bob bene
let result2 = buildName("Bob", "Adams", "Sr.");  // 錯誤,引數太多了
let result3 = buildName("Bob", "Adams");  // 正確 Bob Adams
  • 剩餘引數
function addNumbers(...nums:number[]) {  
    var i;   
    var sum:number = 0; 
    
    for(i = 0;i<nums.length;i++) { 
       sum = sum + nums[i]; 
    } 
    console.log("和為:",sum) 
 } 
 addNumbers(1,2,3)  // 6
 addNumbers(10,10,10,10,10) // 50
  • 匿名函式
    可以將匿名函式賦值給一個變數,這種表示式就成為函式表示式
var res = function( [arguments] ) { ... }
  • 建構函式
var myFunction = new Function("a", "b", "return a * b"); 
var x = myFunction(4, 3); 
console.log(x);
  • 箭頭函式
var foo = (x:number)=>10 + x 
console.log(foo(100))      //輸出結果為 110

Map物件

  • 建立/初始化Map
let myMap = new Map([
        ["key1", "value1"],
        ["key2", "value2"]
    ]); 

聯合型別

可以透過管道(|)將變數設定多種型別,賦值時可以根據設定的型別來賦值。

let val:string|number;
let arr:number[]|string[]; 

介面

介面不能轉換為 JavaScript。 它只是 TypeScript 的一部分。

  • 介面定義
interface interface_name { 
}
  • 介面屬性、方法、使用
interface IPerson { 
    firstName:string, 
    lastName:string, 
    sayHi: ()=>string 
} 
 
var customer:IPerson = { 
    firstName:"Tom",
    lastName:"Hanks", 
    sayHi: ():string =>{return "Hi there"} 
} 
  • 介面和陣列
    介面中我們可以將陣列的索引值和元素設定為不同型別,索引值可以是數字或字串。
interface ages { 
   [index:string]:number 
} 
 
var agelist:ages; 
 // 型別正確 
agelist["runoob"] = 15  
 
// 型別錯誤,輸出  error TS2322: Type '"google"' is not assignable to type 'number'.
// agelist[2] = "google"

介面繼承

  • 單介面繼承
interface Person { 
   age:number 
} 
 
interface Musician extends Person { 
   instrument:string 
} 
 
var drummer = <Musician>{}; 
drummer.age = 27 
drummer.instrument = "Drums" 
console.log("年齡:  "+drummer.age)
console.log("喜歡的樂器:  "+drummer.instrument)
  • 多介面繼承
interface IParent1 { 
    v1:number 
} 
 
interface IParent2 { 
    v2:number 
} 
 
interface Child extends IParent1, IParent2 { } 
var Iobj:Child = { v1:12, v2:23} 
console.log("value 1: "+Iobj.v1+" value 2: "+Iobj.v2)

例項

class Car { 
   // 欄位
   engine:string; 
   
   // 建構函式
   constructor(engine:string) { 
      this.engine = engine 
   }  
   
   // 方法
   disp():void { 
      console.log("函式中顯示發動機型號  :   "+this.engine) 
   } 
} 
 
// 建立一個物件
var obj = new Car("XXSY1")
 
// 訪問欄位
console.log("讀取發動機型號 :  "+obj.engine)   // 讀取發動機型號 :  XXSY1
 
// 訪問方法
obj.disp()  // 函式中顯示發動機型號  :   XXSY1

類的繼承

TypeScript 一次只能繼承一個類,不支援繼承多個類,但 TypeScript 支援多重繼承(A 繼承 B,B 繼承 C)。

class child_class_name extends parent_class_name

類的繼承:例項中建立了 Shape 類,Circle 類繼承了 Shape 類,Circle 類可以直接使用 Area 屬性

class Shape { 
   Area:number 
   
   constructor(a:number) { 
      this.Area = a 
   } 
} 
 
class Circle extends Shape { 
   disp():void { 
      console.log("圓的面積:  "+this.Area) 
   } 
}
  
var obj = new Circle(223); 
obj.disp()

繼承類的方法重寫

類繼承後,子類可以對父類的方法重新定義,這個過程稱之為方法的重寫。
其中 super 關鍵字是對父類的直接引用,該關鍵字可以引用父類的屬性和方法。

class PrinterClass { 
   doPrint():void {
      console.log("父類的 doPrint() 方法。") 
   } 
} 
 
class StringPrinter extends PrinterClass { 
   doPrint():void { 
      super.doPrint() // 呼叫父類的函式
      console.log("子類的 doPrint()方法。")
   } 
}

static 關鍵字

static 關鍵字用於定義類的資料成員(屬性和方法)為靜態的,靜態成員可以直接透過類名呼叫。

class StaticMem {  
   static num:number; 
   
   static disp():void { 
      console.log("num 值為 "+ StaticMem.num) 
   } 
} 
 
StaticMem.num = 12     // 初始化靜態變數
StaticMem.disp()       // 呼叫靜態方法

instanceof 運算子

instanceof 運算子用於判斷物件是否是指定的型別,如果是返回 true,否則返回 false。

class Person{ } 
var obj = new Person() 
var isPerson = obj instanceof Person; 
console.log("obj 物件是 Person 類例項化來的嗎? " + isPerson);

訪問控制修飾符

TypeScript 中,可以使用訪問控制符來保護對類、變數、方法和構造方法的訪問。TypeScript 支援 3 種不同的訪問許可權。

  • public(預設) : 公有,可以在任何地方被訪問。
  • protected : 受保護,可以被其自身以及其子類訪問。
  • private : 私有,只能被其定義所在的類訪問。
class Encapsulate { 
   str1:string = "hello" 
   private str2:string = "world" 
}
 
var obj = new Encapsulate() 
console.log(obj.str1)     // 可訪問 
console.log(obj.str2)   // 編譯錯誤, str2 是私有的

類和介面

類可以實現介面,使用關鍵字 implements,並將 interest 欄位作為類的屬性使用。

interface ILoan { 
   interest:number 
} 
 
class AgriLoan implements ILoan { 
   interest:number 
   rebate:number 
   
   constructor(interest:number,rebate:number) { 
      this.interest = interest 
      this.rebate = rebate 
   } 
} 
 
var obj = new AgriLoan(10,1) 
console.log("利潤為 : "+obj.interest+",抽成為 : "+obj.rebate )

物件

Typescript 中的物件必須是特定型別的例項。

var sites = {
    site1: "Runoob",
    site2: "Google",
    sayHello: function () { } // 型別模板
};
sites.sayHello = function () {
    console.log("hello " + sites.site1);
};
sites.sayHello();

泛型

泛型識別符號 T、U、V等

泛型函式(Generic Functions)

建立一個可以處理不同型別的函式

function identity<T>(arg: T): T {
    return arg;
}

// 使用泛型函式
let result = identity<string>("Hello");
console.log(result); // 輸出: Hello

let numberResult = identity<number>(42);
console.log(numberResult); // 輸出: 42

泛型介面(Generic Interfaces)

// 基本語法
interface Pair<T, U> {
    first: T;
    second: U;
}

// 使用泛型介面
let pair: Pair<string, number> = { first: "hello", second: 42 };
console.log(pair); // 輸出: { first: 'hello', second: 42 }

泛型類(Generic Classes)

// 基本語法
class Box<T> {
    private value: T;

    constructor(value: T) {
        this.value = value;
    }

    getValue(): T {
        return this.value;
    }
}

// 使用泛型類
let stringBox = new Box<string>("TypeScript");
console.log(stringBox.getValue()); // 輸出: TypeScript

泛型約束(Generic Constraints)

在這個例子中,定義了一個泛型函式 logLength,它接受一個型別為 T 的引數,但有一個約束條件,即 T 必須實現 Lengthwise 介面,該介面要求有 length 屬性。因此,可以正確呼叫 logLength("hello"),但不能呼叫 logLength(42),因為數字沒有 length 屬性。

// 基本語法
interface Lengthwise {
    length: number;
}

function logLength<T extends Lengthwise>(arg: T): void {
    console.log(arg.length);
}

// 正確的使用
logLength("hello"); // 輸出: 5

// 錯誤的使用,因為數字沒有 length 屬性
logLength(42); // 錯誤

泛型與預設值

// 基本語法
function defaultValue<T = string>(arg: T): T {
    return arg;
}

// 使用帶預設值的泛型函式
let result1 = defaultValue("hello"); // 推斷為 string 型別
let result2 = defaultValue(42);      // 推斷為 number 型別

TypeScript 名稱空間

看完感覺我不是特別理解,先放連結在這裡

相關文章