TypeScript基礎語法筆記

前言

TypeScript是由微軟開發的一個JavaScript超集,主要提供了類型系統和對ES6的支持。正如TypeScript的官網所說:node

TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.

譯:TypeScript是JavaScript的類型化超集,可以編譯爲純JavaScript語言。typescript

使用TypeScript,可以校驗變量的類型,正由於可以校驗變量的類型,它彌補了JavaScript的語法中,弱類型、動態類型語言的缺陷。TypeScript聲明的變量是一種靜態類型,在代碼編譯時報錯,相比JavaScript的運行時報錯,可以提早發現代碼錯誤,及時糾正。npm

TypeScript靜態類型不只指變量的類型不可修改,同時也說明,變量中存在的方法和屬性也基本肯定了下來。canvas

如下是對TypeScript語法的基礎知識的梳理,包含的內容如思惟導圖所示。
TypeScript基礎語法.png數組

安裝

安裝TypeScript

安裝TypeScript以前,先安裝一下node。
全局安裝TypeScript函數

npm install typescript -g

可能這樣會報沒有權限的錯誤,這時在前面加sudo(mac爲例),而後輸入密碼能解決這個問題。若是要安裝指定版本,加@版本號。優化

sudo npm install typescript@3.6.4 -g

新建一個ts文件this

mkdir demo1.ts

裏面先寫點東西,以方便後面的操做。spa

const  count11:  number =  1;

console.log(count11);

而後命令行執行:插件

tsc demo1.ts

tsc表示把ts文件編譯成js文件。隨後能夠看到目錄中多出一個demo1.js的文件,接着執行:

node demo1.js

在控制檯中能看到打印出的1,就是count11這個變量值。

至此,能夠看到從編譯ts文件到控制檯打印輸出結果,須要分兩步,但這裏有個更好的方法,全局安裝一個叫ts-node的插件能夠進行優化,直接在控制檯輸出結果,但沒法生成編譯後但js文件。

這裏須要注意的是,須要全局安裝ts-node,試過局部安裝了一下行不通。
全局安裝ts-node

sudo npm install ts-node -g

而後想要執行哪一個文件,就直接:

ts-node 那個文件.ts

基礎語法

靜態類型

TypeScript的靜態類型包括基礎類型和對象類型,基礎類型有number、string、void、boolean、null、undefined......對象類型有對象、數組、類、函數。

// 基礎類型舉例

const  num1:  number = 1; // number

const  str1:  string = 'abcd'; // string

const  nothing:  null = null; //null

const  uf:  undefined = undefined; // undefined

const  right:  true = true; // boolean

function  func1():  void { // void,表示函數沒有返回值
    console.log('void');
}

console.log(num1, str1, nothing, uf, right);
func1();

image.png

// 對象類型舉例

// 對象

const  obj1: {

height:  number,

width:  number

} = {

height:  100,

width:  100

};


// 數組
const  arr1:  number[] = [1, 2, 3]; // 這裏表示的是數組每一個元素都是number類型 


// 類
class  Geometry {

vector:  number;

face:  number

}

const  geom1:  Geometry =  new  Geometry();

geom1.vector = 8;

geom1.face = 6;

  
// 函數
const addXY: (x: number, y: number) => number = (x, y) => {
    return x + y;
}
// 上面函數等價於
const addXY = (x: number, y: number): number => {
    return x + y;
}

console.log(obj1.height, obj1.width);

console.log(arr1);

console.log(geom1.vector, geom1.face);

console.log(addXY(1, 1));

image.png

類型註解與類型推斷

類型註解的意思是,須要明確地寫出變量的類型,而類型推斷指的是不須要明確地指定變量的類型。通常可以由Typescript進行類型推斷的變量不須要進行類型註解,這個最多見的就是直接像JavaScript那樣聲明賦值給了一個變量,那麼TypeScript就能夠推斷這個變量是對應的類型,怎麼檢測到這個變量的類型呢?使用vs code能夠查看。

舉個例子。
一、類型註解的例子

// 類型註解
let num2: number;

num2 = 2;

image.png

若是是聲明、賦值分開寫,又沒有類型註解,則沒法作到類型推斷,這時,類型是any。

// 沒法進行類型推斷 num2的類型顯示any
let num2;

num2 = 2;

二、類型推斷的例子

// 類型推斷
let  num3 = 133;

image.png

// 類型推斷
const  obj2 = {
    left:  50,
    top:  100,
    radius:  '50%'
}

image.png

如下這個例子,說明了ts沒法分析變量的類型,致使變量類型成了any。因此這裏是須要用類型註解的。

function  addXY2(x, y) {
    return  x  +  y;
}
const  totals2 = addXY2(1, 7);

image.png

使用了類型註解後,totals2變量類型肯定了,而不是以前的any。

function  addXY2(x:  number, y:  number) {
    return  x  +  y;
}
const  totals2 = addXY2(1, 7);

image.png

函數相關類型

前面寫過靜態類型爲函數類型,指的是一個函數做爲變量,也就是變量是函數類型的變量。而這裏的函數相關類型指的是一個函數自身,內部的返回值類型和函數參數的解構。

函數的返回值類型

函數的返回值能夠是靜態類型,好比number、string、boolean、類class、數組等等。

數組做爲返回值
function  addXY3 (x: number, y: number): number[] {
    return [x + y];
}

const totals3 = addXY3(1, 8);

console.log(totals3);

image.png

image.png

string做爲返回值
function addXY3 (x: number, y: number): string {
    return x + y + 'px';
}

const totals3 = addXY3(1, 8);

console.log(totals3);

image.png

image.png

class做爲返回值
class computedWidth {
    width: number;
}

function addXY3 (x: number, y: number): computedWidth {
    return {
        width:  x + y
    };
}

const  totals3 = addXY3(1, 8);

console.log(totals3);

image.png

image.png

有兩個特殊的須要注意一下。

void指的是函數沒有返回值,一般在寫JavaScript的代碼時,寫的函數會存在沒有返回值的狀況,這時使用void便能很好地指明函數沒有返回值,一旦不當心多寫了return xxx; 便會報錯,及時糾正。

never指的是函數永遠不會執行到最後。

// never
function  addXY5(x: number, y: number): never {
    throw new Error();
    console.log(x + y);   // 這一行沒法執行到
}

函數參數解構賦值

當函數的參數是一個對象的時候,須要注意參數的解構賦值。以前有寫過函數的參數的類型註解,但那些都是像number、string這樣的類型,而像對象類型的參數的類型註解尚未提過。

若是參數是對象類型,須要這樣寫。

// 函數參數解構正確寫法
function addXY4({ x, y }: { x: number, y: number }): number {
    return x + y;
}
const  totals4 = addXY4({ x: 2, y: 7 });

而不是這樣寫,會報錯。

// 函數參數解構錯誤寫法
function addXY4({ x: number, y: number }): number {
    return  x + y;
}
const totals4 = addXY4({ x: 2, y: 7 });

數組和元組

數組

// 數組
const strArr: string[] = ['a', 'c', 'b'];

const arrAny: (number | string | boolean)[] = ['1', 2, true];

const objArr: { width: number, height: number }[] = [{ width:  100, height: 100 }];
// 使用類型別名 type
type ComputedArea = { width: number, height: number };

const objArr2: ComputedArea[] = [{ width: 50, height: 10 }];
// class的狀況
class  Geometry{
    left: number;
    top: number;
    id: string;
}

const geomList1: Geometry[] = [
    {
        left: 100,
        top: 100,
        id: 'AB001'
    },
    new  Geometry()
];

geomList1[1].left = 200;
geomList1[1].top = 200;
geomList1[1].id = 'AB002';

console.log(geomList1);

image.png

元組

//元組,與數組的區別是元素的類型按順序指定,不可錯位
const student1: [string , string , number] = ['a001', 'Tom', 23];
// 寫個複雜點的
const  studentList1: [string, string ,number][] = [
    ['a001', 'Tom', 22],
    ['a002', 'Jerry', 23],
    ['a003', 'Jane', 23]
]
console.log(studentList1);

image.png

interface接口

interface接口與type類型別名的區別

interface接口的做用是把一些共有的屬性和方法提出來放到接口裏面,接口可供變量使用,做爲一個對象類型(對象、函數等)。interface與type類型別名的區別是,interface只能是對象類型,而type能夠是其餘的基礎類型,不單是對象類型。

接口中的只讀屬性

接口能夠定義只讀模式的屬性,使用readonly標識。

接口中容許屬性可選

接口中的屬性有時不是全部使用這個接口的變量都須要,這時能夠在屬性名與冒號之間加上一個問號「?」,這個屬性將做爲可選屬性使用。

接口容許有其餘屬性

有時使用接口的變量有本身的屬性,而不是接口中定義的,這時,若是在接口中加上[propName: string]: any,將表示使用這個接口的變量能夠自定義本身的屬性而不須要在接口中存在。
以上所列出的接口的一些特色,在如下的代碼中舉了些例子。

interface Person {
    name: string,
    age?: number,
    readonly id: string,
    [propName: string]: any
}
function getName (person: Person): string {
    return person.name;
}

function setName (person: Person, name: string): void {
    person.name = name;
}

const Jane = getName({
    name: 'Jane',
    age: 23,
    id: '0a001',
    weight: '60kg'
});

const  resetJane = setName({
    name: 'Jane',
    id: '0a002'
}, 'Tom');

類class應用接口

class John implements Person {
    name:  'abcd';
    id:  '0a003';
}

接口繼承

// interface
interface Person {
    name: string,
    age?: number,
    readonly id: string,
    [propName: string: any
}

interface female extends Person {
    tall: string
}

類的定義與繼承

// 類的定義
class  Geometry {
    counts = 7;
    getCounts() {
        return this.counts;
    }
}

const  geom6 = new Geometry();

console.log(geom6.getCounts());

image.png

// 類的繼承
class Geometry {
    counts = 7;
    getCounts() {
        return this.counts;
    }
}

class Vector2 extends Geometry {
    getVectors () {
        return 8;
    }
}

const geom6 = new Vector2();

console.log(geom6.getCounts());
console.log(geom6.getVectors());

image.png

若是在子類裏面又重寫了一遍父類的方法或屬性,子類的會覆蓋父類的。

class Vector2 extends Geometry {
    counts = 0;
    getCounts() {
        return this.counts;
    }
    getVectors () {
        return 8;
    }
}

image.png

若是不想子類裏重寫的方法、屬性覆蓋父類,那麼能夠使用super。

class Geometry {
    counts = 7;
    getCounts() {
        return this.counts;
    }
}

class Vector2 extends Geometry {
    getCounts() {
        return super.getCounts() + 9;
    }
    getVectors () {
        return 8;
    }
}

const  geom6 = new Vector2();

console.log(geom6.getCounts());
console.log(geom6.getVectors());

image.png

類中的訪問類型

public

// 類的訪問類型--public
class Canvas1 {
    width: string; // 默認是public
    public height: string;  // 能夠在子類、類的外部使用
    getWidth() {
        return this.width;
    }
}

class SubCanvas1 extends Canvas1 {
    getHeight() {
        console.log(this.height);
    }
}

const  subCanvas1 = new SubCanvas1();
subCanvas1.height = '100px';

console.log(subCanvas1.height);

image.png

// 類的訪問類型--private
class Canvas1 {
    private width: string; // 只容許類內使用,在子類或類的外部使用都不行
    public height: string;
    getWidth() {
    return this.width;
    }
}
// 類的訪問類型--protected
class Canvas1 {
    private width: string; // 只容許類內使用
    public height: string;
    getWidth() {
        return this.width;
    };
    protected background: string; // 容許在類的內部及子類中訪問,類外不可訪問
}

class SubCanvas1 extends Canvas1 {
    getHeight() {
        console.log(this.height);
    }
    getBackground() {
        console.log(this.background);
    }
}
// 類的構造器
class  Canvas2 {
    // 傳統寫法
    public width: string;
    constructor(width: string) {
        this.width = width;
    }
}

const canvas2 = new Canvas2('100px');

console.log(canvas2.width);
// 類的構造器
class  Canvas2 {
    // 簡化寫法
    constructor(public width: string) {}
}

const  canvas2 = new Canvas2('100px');

console.log(canvas2.width);

image.png

// 子類有構造器,那麼子類要手動調用一下父類的構造器,不管父類有沒有寫構造器
class Canvas2 {
    // 簡化寫法
    constructor (public  width:  string) {}
}

class SubCanvas2 extends Canvas2 {
    constructor (public  id:  number) {
        super('100px');     // 手動調用父類構造器,有參傳參
    }
}

const subCanvas2 = new SubCanvas2(10001);

console.log(subCanvas2);

image.png

至此,最近學的ts基礎語法筆記已記錄完畢,後續會對進階的知識作補充。

相關文章
相關標籤/搜索