TypeScript入門指南

1 介紹

1 TypeScript介紹

TypeScript是微軟開發的JavaScript的超集,TypeScript兼容JavaScript,能夠載入JavaScript代碼而後運行。javascript

2 TypeScript與JavaScript比較

TypeScript與JavaScript相比進步的地方 包括加入註釋,讓編譯器理解全部支持的對象和函數,編譯器會移出註釋,不會增長開銷,增長一個完整的類機構,使之更新是傳統的對象語言java

3 語法特性

類 classes
接口interface
模塊 modules
node

2 安裝

1 安裝 node 的 .d.ts 庫

仍是由於是node.js開發,咱們要安裝node的ts庫, 爲了強類型,主要仍是爲了智能感知。程序員

npm install @types/node --dev-save
複製代碼

2 安裝typescript

npm install -g typescript
複製代碼
  • 或者更新TypeScript Compiler
    輸入指令:npm update -g typescript
    查看版本指令tsc -v

新建一個文件夾 tstypees6

3 初始化npm

npm init -y
複製代碼
  • 建立tsconfig.json
    typescript 的項目都須要一個tsconfig.json
    輸入命令
tsc --init
複製代碼

會建立一個這樣內容的tsconfig.jsontypescript

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es6",
    "removeComments": false,
    "noImplicitAny": false,
    "sourceMap": true,
    "allowJs": true
  },
  "exclude": ["node_modules"]
}
複製代碼

由於寫node.js你能夠修改targetes6, 要調試把 sourceMap改成true, 添加allowjstrue,就能夠ts和js混合用了.npm

初始化工程
npm init
tyc --init
ctrl + shift + b編譯,能夠選擇watch或者buildjson

image.png

3 基本數據類型

0 對比數據類型

首先咱們瞭解一下JavaScript的基本數據類型數組

基本數據類型(值類型)

  • Number  數字
  • String  字符串
    • 單引號包裹起來的都是字符串(單雙號沒有區別)
  • Boolean  布爾
    • true false => 布爾值只有兩個值
  • null 空對象指針
  • undefined  未定義

TypeScript 基本數據類型

  • Number 數字
  • Boolean 布爾
    • true false => 布爾值只有兩個值
  • String 字符串
  • Any 任何數據類型
  • Array 數組
  • Enum 枚舉
  • Void 返回爲任一

1 Boolean 布爾值

var isBoon: boolean = false; // 必須給一個初始化的值
console.log(isBoon);
複製代碼

2 Number 數字

var num : number = 10;
console.log(num);
複製代碼

3 String 字符串

var str:string="iwen"
console.log(str);
複製代碼

4 Array 數組的定義

let array1:Array<number>;
let array2:number[];
let array1:Array<number> = new Array<number>();
let array2:number[] = [123];
複製代碼

5 enum_ 枚舉類型_

enum Color {Red,Green,Blue};
var colorName: String = Color[1]
console.log(colorName);
// 獲取枚舉類型的值

enum ColorVal { Red=1, Green=2, Blue=5 };
var colorName:String = ColorVal[5]
console.log(colorName);
// 經過val值去獲取key值

enum ColorKey { Red, Green, Blue}
var c:ColorKey = ColorKey.Green;
console.log(c);
// 獲取枚舉類型的下標
複製代碼

6 any 任何一種數據類型

var notSure:any =10;
notSure="hello";
notSure=false
console.log(notSure);
// 獲得最後一次數據類型
複製代碼

7 返回值

// 必須是指定的返回值
function tell():string{
    return "hello"
}

// 能夠沒有任何返回值的話
function tellNull():void {
   
}

複製代碼

4 函數

在JavaScript中咱們學會了兩種參數bash

在JavaScript中

1.命名函數

function add(x,y) {
    return x+y;
}
複製代碼

2.匿名函數

var myAdd = function(x,y){
    return x+y;
}
複製代碼

在TypeScript中

1 函數-可選和默認參數

// 設置變量,包括返回值
function add(x: number, y: number): number {
    return x+y;
}


// 註解模式寫法
var myAddts: (name: string, age: number)=>number=function(n:string,a:number):number{
    return a;
}
複製代碼

2 可變參數

增長❓後變成,能夠更變的值

function buildName(firstName:string,lastName?:string){
    if (lastName) {
        return `${firstName} ${lastName}`
    }else{
        return `${firstName}`
    }
    
}

var name1 = buildName("ime","isee");
var name2 = buildName("im1")
複製代碼

3 設置默認參數

function buildName2(firstName: string, lastName ="isee") {
    if (lastName) {
        return `${firstName} ${lastName}`
    } else {
        return `${firstName}`
    }
}

var name3 = buildName2("im1");
var name4 = buildName2("ime", "isee");
複製代碼

4 可變參數

function peopleName(firstName:string,...restOfname:string[]) {

	return firstName + "" + restOfname.join(" ")

}
複製代碼

5 Lambads 和 this 關鍵字的使用

var people ={
    name:['iwen','ime','if','bean'],
    getName:function(){
        return ()=>{
            var i = Math.floor(Math.random()*4)
            return {
                n:this.name[i]
            }
        }
    }
}
複製代碼
var people ={
    name:['iwen','ime','if','bean'],
    getName:()=>{
        return ()=>{
            var i = Math.floor(Math.random()*4)
            return {
                n:this.name[i]
            }
        }
    }
}
複製代碼

6 重載

function attr(name:string):string; function attr(age: number): number; function attr(nameorage: any): any{
    if (nameorage){
        console.log(nameorage);
    }
}
attr("姓名")
複製代碼

5 類

1 類的建立

class Person{
    name:string;
    age:number;
    constructor(name:string,age:number) {
        this.name = name;
        this.age = age;
    }
    print(){
        return this.name+":"+this.age
    }
}
var p = new Person("a",12);
p.print();
複製代碼

2 類的繼承

class Student extends Person{
    school: string;
    constructor(school: string) {
        super('ime', 800); // 繼承人類這個屬性
        this.school = school;
    }
    tell(){
        return this.name + ":" + this.age + this.school;
    }
}
var s = new Student("學校");
s.tell();
複製代碼

3 訪問修飾符

關於類中成員訪問修飾符:
ts類中成員(成員屬性、成員方法)的訪問修飾符,相似於java中類成員的訪問修飾符,不一樣的是ts中默認是被public修飾。
public :公有          在當前類裏面、 子類  、類外面均可以訪問
protected:保護類型    在當前類裏面、子類裏面能夠訪問 ,在類外部無法訪問
private :私有         在當前類裏面能夠訪問,子類、類外部都無法訪問

class People{
    private name:string; // 私有
    public age:number; // 公有
    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }
    print(){
        return this.name+":"+this.age
    }
}
複製代碼
class Student extends People{
    constructor() {
        super('ads',200);
    }
    tell(){
        return "222";
    }
}
var s = new Student();
s.age = 12;
// s.name = 12; 此時是沒法調用私有變量的
s.print();
console.log(s.print());
複製代碼

4 封裝的實現

class Hello{
    private _name:string;
    constructor() {
        this._name= _name
    }
    set name(name:string){
        this._name = name
    }
    get name():string{
        return this.name
    }
    tell(){
        return this._name;
    }
}
var h = new Hello();
h.name='iwen';
console.log(h.tell());
複製代碼

5 Static和使用技巧

class Greeter{
    greeting:string;
    constructor(message:string) {
        this.greeting = message
    }
    greet(){
        return 'Hello,'+this.greeting;
    }
}
var green:Greeter;
green=new Greeter('iwen');
console.log(green.greet());
複製代碼

6 接口(Interfaces)

**咱們先定義個接口,而後把符合接口定義的對象傳進去,這樣能提升代碼可讀性。 **
須要注意的是:
若是咱們不給傳進去的對象指定是接口類型的數據,那麼傳入的對象參數能夠包含其餘屬性,編譯器只會檢查那些必需的屬性是否存在,而且其類型是否匹配。 
若是咱們給對象指定是接口類型的數據,那麼,對象的屬性必須和定義好的接口的必要屬性一致。必要屬性不能多也不能少。

1 建立接口

function printeLabel(labelObj:{lable:string}) {
    console.log(labelObj.lable);
}

var myObj = { lable:"Hello"}
printeLabel(myObj);
複製代碼
interface LabelValue{
    label:string
}

function printeLabel(labelObj:LabelValue) {
    console.log(labelObj.label);
}

var myObj = {label:"Hello-1"};
printeLabel(myObj)
複製代碼

2 可選屬性

在實際應用中,接口裏的屬性不全都是必需的。 有些是隻在某些條件下存在,或者根本不存在。在這種個狀況下能夠是用接口的可選屬性去定義。 
以下代碼所示,name和age被定義爲可選屬性,那麼在傳對象的時候name和age就無關緊要。

interface USB{
    name:string;
    age?:number;
}
function printUSB(pu:USB){
    console.log(pu.name);
    console.log(pu.age);
}
var my = { name: "ime"}
printUSB(my)
複製代碼

只讀屬性

若是咱們但願對象屬性只能在對象剛剛建立的時候修改其值。 咱們能夠在屬性名前用 readonly來指定只讀屬性。

interface Point{
   readonly x:number;
   readonly y:number;
}
 
function getPoint(p:Point){
    console.log(p.x);
    console.log(p.y);
}
let point:Point={x:1,y:2};
// point.x=2;//錯誤 這裏不能再子修改值
getPoint(point);
複製代碼

4 定義只讀數組

只讀數組也同樣,一旦定義後不能再修改數組

let a:ReadonlyArray<number> =[1,2,3,4,5];
// a[0]=2;//不能再修改該數組
// a.length=20;
複製代碼

5 函數類型

接口能夠描述javascript的任何對象,不只能描述對象的屬性類型,固然也能描述對象的函數類型。
以下代碼所示,接口描述了這個函數的參數類型和返回值類型

interface SearchFunc{
    /*在這裏咱們描述了這個接口有個函數 這個函數傳進去2個string類型的參數 而後返回一個boolean類型的數據*/
    (source:string,subString:string):boolean
}
var mySearch: SearchFunc;
mySearch = function (source: string, subString: string){
    var result = source.search(subString);
    if (result!=-1) {
        return true
    }
    else{
        return false
    }
}
複製代碼

6 接口的數組類型(可索引的類型)

跟接口描述函數類型差很少,咱們也能夠描述那些可以「經過索引獲得」的類型,好比經過下標獲取數組中的值 a[2];須要注意的是,索引器的類型只能爲 number 或者 string。

interface StringArray{
    /*描述的一個數組 這個數組裏面的元素是string類型 而且只能經過number類型來索引 [index:number]是索引器 string [index:number]:string; // age:number; //須要注意的是,當咱們將這個接口是數組類型時,那麼,接口中定義的其它屬性的類型都必須是該數組的元素類型。 這裏的number類型是報錯的 } var myArray: StringArray; myArray=['iwen','ime']; console.log(myArray[1]) 複製代碼

7 Class 類型

所謂類類型,就是一個類去實現接口,而不是直接把接口拿來用,這更符合咱們的使用習慣。

interface IClock{
    /*定義了一個接口 這個接口中有一個屬性和一個方法*/
    currentTime:Date;
    getTime(d:Date);
}
/*Time類實現IClock接口*/
class Time implements IClock{
    currentTime:Date;
    getTime(d:Date){
        this.currentTime=d;
    }
}

複製代碼

8 擴展接口

在TypeScript中,接口跟類同樣是能夠相互繼承的, 這讓咱們可以從一個接口裏複製成員到另外一個接口裏,能夠更靈活地將接口分割到可重用的模塊裏。

/*接口能夠繼承接口 而且能夠多繼承*/
interface shape{
	color:string;
}
interface pen extends shape{
	width:number;
}
let circle=<pen>{};//注意這裏的寫法,建立一個對象並指定泛型 circle.color="red";//這裏能夠獲取color屬性 circle.width=2;//有width屬性 複製代碼

9 一個接口能夠繼承多個接口,建立出多個接口的合成接口

/*接口能夠繼承接口 而且能夠多繼承*/
 
interface shape{
    color:string;
}
interface pen extends shape{
    width:number;
}
 
interface Circle extends shape,pen{
    point:number[];
}

let c=<Circle>{};//注意這裏的寫法,建立一個對象並指定泛型 c.point=[1,2]; c.color="red"; c.width=1; 複製代碼

10 接口繼承與混合類型

所謂的混合類型就是在一個接口中定義多種類型,好比屬性,函數,數組等。

interface Counter {
    (start: number): string;
    interval: number;
    reset(): void;
}
 
function getCounter(): Counter {
    let counter = <Counter>function (start: number) { }; counter.interval = 123; counter.reset = function () { }; return counter; } let c = getCounter(); c(10); c.reset(); 複製代碼

7 泛型

泛型就是在編譯期間不肯定方法的類型(普遍之意思),在方法調用時,由程序員指定泛型具體指向什麼類型

_

1 認識泛型

在代碼的過程當中,有些時候不肯定要傳什麼類型的參數,可是又但願被校驗

function Hello<T>(arg:T):T{
    return arg;
}
var output = Hello<string>("Hello ime");
複製代碼

2 泛型的應用

function Hello<T>(str:T[]):T[] {
    console.log(str.length);
    return str
}

var list:Array<string> = Hello<string>(['1','2','3'])
for (let i = 0; i < list.length; i++) {
    console.log(list[i]);
}
複製代碼

3 泛型類

class GetMin<T>{
    arr:T[]=[];
    add(ele:T){
        this.arr.push(ele);
    }
   min():T{
      var min=this.arr[0];
      this.arr.forEach(function (value) {
         if(value<min){
             min=value;
         }
      });
      return min;
   }
}

 var gm1= new  GetMin<number>();
  gm1.add(5);
  gm1.add(3);
  gm1.add(2);
  gm1.add(9);
console.log(gm1.min());
var gm2= new GetMin<string>();
gm2.add("tom");
gm2.add("jerry");
gm2.add("jack");
gm2.add("sunny");
console.log(gm2.min());
複製代碼

4 泛型函數接口

interface ConfigFn{
   <T>(value:T):T;
}

var getData:ConfigFn=function<T>(value:T):T{
   return value;
}

getData<string>('張三');
// getData<string>(1243); //錯誤
// 相似 Map<String,Object> Param 接口

interface Param{
   [index:string]:any
}
複製代碼

8 模塊

1 全局模塊

默認狀況下,當你開始在一個新的 TypeScript 文件中寫下代碼時,它處於全局命名空間中。如在 foo.ts 裏的如下代碼:

const foo = 123;
複製代碼

若是你在相同的項目裏建立了一個新的文件 bar.ts,TypeScript 類型系統將會容許你使用變量 foo,就好像它在全局可用同樣:

const bar = foo; // allowed
複製代碼

毋庸置疑,使用全局變量空間是危險的,由於它會與文件內的代碼命名衝突。咱們推薦使用下文中將要提到的文件模塊。

2 文件模塊

它也被稱爲外部模塊。若是在你的 TypeScript 文件的根級別位置含有 import 或者 export,它會在這個文件中建立一個本地的做用域。所以,咱們須要把上文 foo.ts 改爲以下方式(注意 export 用法)

export const foo = 123;
複製代碼

在全局命名空間裏,咱們再也不有 foo,這能夠經過建立一個新文件 bar.ts 來證實:

const bar = foo; // ERROR: "cannot find name 'foo'"
複製代碼

若是你想在 bar.ts 裏使用來自 foo.ts 的內容,你必須顯式導入它,更新 bar.ts 以下所示:

import { foo } from './foo';
const bar = foo; // allow
複製代碼

在 bar.ts 文件裏使用 import,不但容許你使用從其餘文件導入的內容,並且它會將此文件 bar.ts 標記爲一個模塊,文件內定義的聲明也不會污染全局命名空間。

3 ES 模塊語法

  • 使用 export 關鍵字導出一個變量(或者類型):

// foo.ts
export const someVar = 123;
export type someType = {
  foo: string;
};
複製代碼
  • export 的寫法除了上面這樣,還有另一種:
// foo.ts
const someVar = 123;
type someType = {
  type: string;
};
export { someVar, someType };
複製代碼
  • 你也能夠重命名變量導出
// foo.ts
const someVar = 123;
export { someVar as aDifferentName };
複製代碼
  • 使用 import 關鍵字導入一個變量或者是一個類型:
// bar.ts
import { someVar, someType } from './foo';
複製代碼
  • 重命名導入變量或者類型:
// bar.ts
import { someVar as aDifferentName } from './foo';
複製代碼
  • 除了指定加載某個輸出值,還可使用總體加載,即用星號(*)指定一個對象,全部輸出值都加載在這個對象上面:
// bar.ts
import * as foo from './foo';
// 你可使用 `foo.someVar` 和 `foo.someType` 以及其餘任何從 `foo` 導出的變量或者類型
複製代碼
  • 僅導入模塊:
import 'core-js'; // 一個普通的 polyfill 庫
複製代碼
  • 從其餘模塊導入後總體導出
export * from './foo';
複製代碼
  • 從其餘模塊導入後,部分導出
export { someVar } from './foo';
複製代碼
  • 經過重命名,部分導出從另外一個模塊導入的項目
export { someVar as aDifferentName } from './foo';
複製代碼

默認導入/導出

我並不喜歡用默認導出,雖然有默認導出的語法:

  • 使用export default
    • 在一個變量以前(不須要使用 let/const/var);
    • 在一個函數以前;
    • 在一個類以前。
// some var
export default (someVar = 123);
// some function
export default function someFunction() {}
// some class
export default class someClass {}
複製代碼
  • 導入使用 import someName from 'someModule' 語法(你能夠根據須要爲導入命名):
import someLocalNameForThisFile from './foo';
複製代碼

大體上和es6一致

相關文章
相關標籤/搜索