TypeScript 要點知識整理

本篇主要是整理一下 typescript 相關的知識點,實際的運用會在下篇文章仔細講解。html

什麼是 TypeScript

TypeScript 是 JavaScript 的一個超級,主要提供了類型系統和對 ES6 的支持。es6

安裝 TypeScript 及編譯 Ts 文件

npm -g install typescrip // 全局安裝 typescript
複製代碼

全局安裝 typescript 後便可在終端使用 tsc 命令了,編譯 ts 文件命令以下:typescript

// hello.ts
function foo(name: string) {
    console.log(`Hello ${name}`);
}
foo('Cooper') // Hello Cooper

tsc hello.ts // 編譯 ts 文件後生成對應的 hello.js 文件
複製代碼

TypeScript 的類型檢查說明

Ts 只會進行靜態類型檢查,若是發現錯誤,編譯的時候就會報錯。平常通常搭配 Eslint 或 Tslint 使用,在編碼過程當中即會報出對應錯誤。express

基本數據類型

經過在變量後加 :類型 聲明變量的類型。npm

1. bolean 布爾值

let isSuccess: boolean = true; // 正確
let isSuccess: boolean = new Boolean(1); // 錯誤,new 產生的是一個Boolean類型的對象,類型爲 Boolean,是一個構造函數,不一樣於基本數據類型 boolean
let isSuccess: Boolean = new Boolean(1); // 正確
let isSuccess: boolean = Bealean(1); // 返回的還是一個基本boolean類型的值
複製代碼

說明: 在 typescript 中,boolean 是基本數據類型,而 Boolean 是一個構造函數,定義爲 boolean 的值不能是 Boolean 對象。其餘基本數據類型亦如此數組

2. 數組

let num: number = 3; // 正確
num = '3'; // 報錯,申明瞭變量爲 number 類型,怎麼能賦 string 類型的值呀!
複製代碼

3. 字符串

let name: string = 'Cooper';
let templetStr: string = `Hello, ${name}`; // es6 模版字符串
複製代碼

4. 空值

JavaScript 中沒有空值(Void)的概念,在 TypeScript 中空值通常用來表示一個函數沒有返回值bash

// 定義一個沒有返回值的返回的函數
function foo(name: string): void {
    console.log(name)
}
複製代碼

5. Null 和 Undefined

定義爲 null 類型的變量只能被賦值爲 null, 定義爲 undefined 的變量只能被賦值爲 undefined函數

let u: undefined = undefined;
let m: null = null;
複製代碼

任意值

定義爲任意值的變量能夠被賦值爲任意類型。在任意類型的變量上訪問任意屬性和方法都是能夠的。聲明一個變量爲 any 類型後,對其進行任意操做返回的都是 any 類型。未聲明類型的變量默認爲 any 類型。oop

let anyValue: any = '123';
anyValue = 1; // 不會報錯,由於 anyValue 的類型爲任意值
複製代碼

注意:any 用起來雖然特別方便,可是建議平常開發能不用就不用,畢竟 TypeScript 是爲了更規範的書寫 Js 代碼,若是所有都定義成 any 類型,那就失去了 TypeScript 的意義。ui

類型推論

若是沒有明確的指明某個變量的類型, 那麼 TypeScript 會依照類型推論的規則推導出一個類型。

let str = 'Cooper';
str = 7; // 報錯,根據類型推論確認 str 爲 string 類型,則不能夠賦 string 外的值
複製代碼

聯合屬性

聯合類型表示取值能夠爲多種類型中的一種,各個類型間使用分隔線 | 鏈接

let strOrNumValue: string | number = 'test';
複製代碼
  • 訪問聯合類型的屬性和方法 當一個變量定義爲聯合類型,咱們只能訪問聯合類型的公共方法和屬性
function getLength(something: string | number) {
    return something.length; // 報錯,number 類型不包含 length 屬性
}
function myToString(something: string | number) {
    return something.toString(); // 正確,number 和 string 類型都包含 toString 方法
}
複製代碼
  • 聯合類型的變量在被賦值後,會根據類型推論的規則推導出一個類型
let something: string | number;
something = 'Cooper';
console.log(something.length) // 5, something 賦值字符串後,被推導爲 string 類型,於是能夠訪問 length 屬性
something = 3
console.log(something.length) // 報錯
複製代碼

對象的類型 - 接口

在 TypeScript 中,咱們用接口來定義對象的類型,接口命名,通常以大寫字母 I 開頭,且 I 後面的首個字母一併大寫,瞭解 Java 的同窗應該很熟悉,這與 Java 是一致的。

interface IPerson {
    name: string;
    age: number;
}
// 接口的全部屬性都須要包含,且各個屬性類型一致,不然報錯
let Cooper: IPerson = {
    name: 'Cooper',
    age: 23
}
複製代碼
  • 可選屬性
    用來表示某個對象中的屬性是可選的。
interface IPerson {
    name: string;
    age?: number; // 咱們在屬性後使用 ? 後表示該屬性爲可選屬性
}
// 可只包含 name 屬性,age爲可選屬性,可不定義,可是不能添加接口未定義屬性
let Cooper: IPerson = {
    name: 'Cooper'
}
複製代碼
  • 任意屬性
interface IPerson {
    name: string;
    age?: string;
    [propName: string]: string;
}
let cooper: IPerson = { // true
    name: 'Cooper',
    gender: 'male' // 添加的任意屬性 gender
}
複製代碼

注意:一旦定義了任意類型,那麼確認屬性和可選的屬性的類型必須是任意屬性類型的子類,舉個例子,以上定義改成

// 報錯,任意屬性爲 string,不包括可選屬性的 number 類型
interface IPerson {
    name: string;
    age?: number;
    [propName: string]: string;
}
// 應改成如下形式
interface IPerson {
    name: string;
    age?: number;
    [propName: string]: string | number; // 上面定義的具體類型也應包含在任意類型
}
複製代碼
  • 只讀屬性 有時候咱們但願有些屬性只能在初始化時被賦值,後續不容許修改,則可使用 readonly 關鍵字來定義
interface IPerson {
    readonly id: number;
    name: string
}
let cooper: IPerson = {
    id: 14202119,
    name: 'Cooper'
}
cooper.id = 14020120 // 報錯,只讀屬性不容許再次修改值
複製代碼

數組的類型定義

在 TypeScript 中數組可使用多種方式定義類型。

  • 類型 + 中括號
let list: number[] = [1, 2, 3]; // 數組中的每一項都 number 類型
複製代碼
  • 數組泛型,Array[T], T 爲泛型
let list: Array<number> = [1, 2, 3];
複製代碼
  • 用接口表示
// key 爲 number 類型,即數組下標,值爲 number 類型,即 value
interface INumberArray {
    [index: number]: number
}
let list: INumberArray = [1, 2, 3]
複製代碼
  • 對象數組的定義
interface IItem = {
    name: string,
    age: number
}
// 數組中是一個對象,且對象中屬性需和定義的一致
let list: IItem[] = [
  {
    name: 'Cooper',
    age: 23
  },
  {
    name: 'Bob',
    age: 23
  },
]
複製代碼

函數類型

  • 函數的聲明方式
// 函數式聲明
function foo(name) {
    console.log(name);
}
// 函數表達式
const mySun = function(x, y) {
    return x + y;
}
複製代碼
  • 函數式聲明定義類型
// 接收兩個 number 的參數,不容許少傳或多傳參數,且函數的返回值必須爲 number 類型
function(x: number, y: number): number {
    return x + y;
}
複製代碼
  • 函數表達式定義類型
let myFun: (x: number, y: number) => number = function(x: number, y: number): number {
    return x + y;
}
// 左側變量的類型可省略,等號左邊會根據類型推論推斷出來,即:
let myfun = function(x: number, y: number): number {
    return x + y;
}
複製代碼
  • 使用接口定義
interface IMyFun {
    (x: number, y: number): boolean
}
let myFun: IMyFun = function(x: number, y: number): boolean {
    return false;
}
複製代碼
  • 可選參數和剩餘參數
// y 爲可選參數
function myFun(x: number, y?: number): number {
    if (y) {
        return x + y;
    }
}
// 剩餘參數
function myFun(x: number, ...ars: any[]) {
    console.log(args);
}
myFun(1, 2, '3'); // [2, '3']
複製代碼

類型斷言

類型斷言即手動(或者說是強制?。?)指定一個變量的類型

  • 語法
<類型>變量
變量 as 類型 // tsx 中僅支持此種方式
複製代碼
function myFun(x: number | string) {
    console.log(<string>x.length); // 此處變量 x 的屬性爲 string | number,想直接使用 length 屬性,則須要經過類型斷言指定 x 的屬性爲 string } 複製代碼
  • 特殊
    當咱們聲明可選參數時,咱們須要先判斷參數存在才能使用
function myFun(x: number, y?: number): number {
    if (y) {
        const result = x + y; // 不進行判斷將會報錯
        return result;
    }
}
// 也可經過斷言
function myFun(x: number, y?: number): number {
    const result = x + !y; // !表示改變量必定存在
    return result;
}
複製代碼

注意:類型斷言不是類型轉換,斷言一個聯合類型中不存在的類型將會報錯。

聲明文件

當咱們直接在項目中引入第三方的模塊,而且使用其方法或者是屬性,ts 是不會報錯的,由於這些類型和方法都是沒有進行聲明的。由於咱們須要使用聲明文件來定義這些屬性和方法的類型。對於一些經常使用的第三方模塊, typescript 社區已經幫咱們定義好了,只要咱們在使用 npm 安裝模塊的時候,在模塊名前帶上 @type/

npm install express --save// 安裝普通的 express 模塊
npm install @/types/express --save-dev// 安裝帶有聲明文件的 express 模塊,只有本地開發環境才進行安裝
複製代碼

對於一些不經常使用的第三方模塊,在 typescript 社區中沒法安裝帶有聲明文件的模塊,咱們能夠在項目的根目錄下建立一個 index.d.ts 文件,在其中對其進行聲明,防止 ts 報錯。

declare module 'so-utils'; // 聲明 so-utils 爲一個模塊,防止 import * from 'so-utils' 報錯
複製代碼

以上可防止模塊引入時報錯,但對於模塊定義的屬性和方法依舊沒有提示,想要完整的代碼提示功能則要定義完整的聲明文件,關於聲明文件的書寫名,參見TypeScript 入門教程 - 聲明文件

內置對象

JavaScript 中有不少定義好的對象,咱們能夠看成定義好的類型來使用。

let bodyDoc: HTMLDocument = document.body; // html文檔流
複製代碼

類型別名

咱們使用 type 關鍵字來聲明類型的別名

type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver
function getName(n: NameOrResolver): Name {
    if (typeof n === 'string') {
        return n;
    } else {
        return n();
    }
}
複製代碼

字符串字面量類型

字符串字面量類型用來約束取值只能是某幾個字符串取值中一個

type eventName = 'click' |  'scroll' | 'mousemove'
// 第二個參數 event 只能是'click' | 'scroll' | 'mousemove'三個中的某一個
function handleEvent(ele: Element, event: EventNames) {
    // do something
}
handleEvent(doument.getELementById('hello'), 'scroll'); // true
handleEvent(doument.getELementById('hello'), 'dbclick'); // 報錯
複製代碼

參考

相關文章
相關標籤/搜索