搜尋
首頁web前端js教程typescript指南詳解

typescript指南詳解

Jun 30, 2017 am 10:48 AM
javascripttypescript

 

typescript指南

#前言

typescript是angularjs2推薦使用的腳本語言。它是由微軟2012年首次發布。 

一.    typescript和javascript的區別

1.從遵循的規範上的角度:

  Javascript遵循ECMA5的規範,TypeScript是語法上對ECMA6的實現。

2.從功能上說:

TypeScript提供了類別、模組和介面來幫助建立元件,更方便寫物件導向的程序,所以被稱為更好的typescript。

3.從支援上說:

所有的瀏覽器都支援ES5及之前的javascript,而沒有瀏覽器支援typescript,所以需要編譯。另外typescript支援所有javascript的語法。

照片顯示了ES5、ES2015、ES2016以及typescript的關係。

二. typescript的安裝與helloworld程式

#(1)npm安裝

 npm install -g typescript@1.8 全局安装了1.8版本的typescript编译器和tsc程序,并且添加到环境变量中。为了确认正常,打印-v命令。
$ npm -v   //首先看一下npm是不是新版本$ npm install -g typescript@1.8. //全局安装typescript$ tsc -v

#顯示typescript的版本是:

(2)運行第一個ts程式。

第一種方式。

首先在1.hello.ts程式中輸入:

console.log("hello world!")

#然後執行指令:

$ tsc 1.hello.ts  //把ts文件转换为等价的hello.js

最後執行node來執行js檔。

$ node 1.hello.js //打印出hello world。成功!

第二種方式。

先裝好typescript和ts-node.

$ npm install typescript@1.8  -g    //装好ts$ npm install  -g ts-node //装ts-node模块,选项是-g哦。

#再執行指令執行檔。

$ ts-node 1.hello.ts //打印hello world,成功!

三. typescript從ES2015和ES2016引入的語法和特性

ES2015和ES2016有比較大的變化。

(1)ES2015的箭頭函數

由來:javascript有一級函數的特性,也就是說,函數能夠當做參數進行傳參,很好的用法不過太囉嗦,所以ES2015提供了箭頭函數,更簡潔。

ts範例1:

var even=[3,1,56,7].filter(el=>!(el%2));//对数组调用过滤器filter函数,!(el%2)只有偶数的取模操作为0,那么整体就是true,所以el获取的是偶数console.log(even);//打印56咯。

透過執行ts-node指令,螢幕顯示結果為:

## ts範例2:

var result=[1,2,3]
    .reduce((total,current)=>total+current,0);//reduce对每个数组元素比如1、2、3调用回调函数,初始值为0。//回调函数的参数是total和current,total是上一次回调函数的值,第一次就为初始值0.// current是当前数组元素的值。返回值是total+current。//那么就清晰了,第一个total为0,当前元素是1,返回的0+1.console.log(result);
透過執行ts-node指令,螢幕顯示結果為:

ts範例3:

var data=[
    {price:10,total:70},
    {price:94,total:340},
    {price:14,total:34}
];var sorted=data.sort((a,b)=>{//a、b为依次遍历的数组元素//这里的对象是函数体var diff=a.price-b.price;if(diff!==0){return diff;
    }return a.total-b.total;
})
console.log(sorted);
透過執行ts-node指令(編譯),螢幕顯示正確的排序結果為:

ts範例4:

function MyComponent(){this.age=42;
    console.log(this);
    setTimeout(()=>{//箭头函数的特性,它的执行上下文指向外层的代码,即组件实例的this对象this.age+=1;
        console.log(this.age);
    },100);//等待100ms,age加1等于43,并打印出来}new MyComponent();
透過編譯,螢幕顯示:

#(2)ES2015和ES2016中的類別

#先說明一下,ES6就是ES2015。 ECMAScript 6(以下簡稱ES6)是JavaScript語言的下一代標準。因為目前版本的ES6是在2015年發布的,所以又稱為ECMAScript 2015。

然後ECMAScript 2016就是ES7。

ES6的類別依然是使用建構子和基於原型的繼承,但是語法更方便簡潔。

下面是ES2016定義類別的語法:

class Human{
    static totalPeople=0;
    _name;//ES2016的属性定义语法    constructor(name){this._name=name;
        Human.totalPeople+=1;
    }
    get name(){return this._name;
    }
    set name(val){this._name=val;
    }//name属性的get和set方法    talk(){return "Hi,I'm"+this.name;
    }
}
class Developer extends Human{
    _languages;//ES2016的属性语法    constructor(name,languages){
        super(name);this._languages=languages;
    }
    get languages(){return this._languages;
    }
    talk(){return super.talk()+" And I Know "+this.languages.join('.');

    }
}var human=new Human("foobar");var dev=new Developer("bar",["javascript"]);
console.log(dev.talk());

喜欢!除了类的定义体是对象外,属性和方法的书写和java很像,我喜欢的方式。

 通过编译,屏幕显示结果为:

(3)定义块级作用域中可见的变量

java和c++是块级作用域。

只列举代码,表现为2点,第一个是特定代码块的变量只能代码块内部可见,第二,嵌套在内部的代码块中也可见。

public class Demo{// 属性块,在类初始化属性时候运行    {int j = 2;// 块级变量    }public void test1() {int j = 3;  // 方法级变量if(j == 3) {//j变量在代码嵌套的内部if语句中可见int k = 5;  // 块级变量        }
}

javascript是函数作用域。

var fns=[];for(var i=0;ifn());

打印结果,很奇怪。

ES6代码:

var fns=[];for(let i=0;ifn());

打印结果:

(4)使用ES2016装饰器进行元编程。

装饰器是ES2016的一个提案,它的依据是“在设计阶段可以对类和属性进行注释和修改”。在angular2很常用,可用来定义组件、指令以及管道,并且还能配合依赖注入机制来使用。

首先,装饰器能干吗。

装饰器典型的用法是把方法和属性标记为过期,另一个应用场景是声明式语法,从而实现面向切面的编程。其实呢,装饰器只是一个语法糖而已。装饰器目前并没有得到真正的使用

Experimental support for decorators is a feature that is subject to change in a future release.
//编写了Person类,它只有一个getter,名字为kidCountclass Person{//kidCount有一个装饰器nonenumerable    @nonenumerable
    get kidCount(){return 42;
    }
}//装饰器函数接收3个参数,最后返回descriptor属性。function nonenumerable(target,name,descriptor){
    descriptor.enumerable=false;//可枚举性return descriptor;
}var person=new Person();for(let prop in person){
    console.log(prop);
}

对应的ES5语法类似于:

descriptor=nonenumerable(Person.prototype,'kidCount',descriptor);//descriptorObject.defineProperty(Person.prototype,'kidCount',descriptor);

接下来,介绍angular 2装饰器的用法。

"app""./app.html""/",component:Home,name:'home'"/",component:About,name:'about'

如果装饰器需要接收参数,那么就定义为接收参数的函数,然后由函数返回真正的装饰器。

 (5)使用ES2015编写模块化的代码

angular 1.x引入了一套模块系统,不过并不支持懒加载特性。angular 2种充分利用了ES2015提供的模块系统。ES2015提供了声明式API,以及使用模块加载器的命令式API。

语法分为export和import两个方面。

第一,看一个简单的DEMO:

math.ts:

export function square(x){return Math.pow(x,2);
}
export function log(x){return Math.log(x);
}
export const PI=Math.PI;

math2.ts,更简洁的写法而已:

function square(x){return Math.pow(x,2);
}function log(x){return Math.log(x);
}
const PI=Math.PI;
export {square,log,PI}

app.ts调用,要编译的是app.ts哦:

import {square,log} from "./math";
console.log(square(2));
console.log(log(100));

屏幕显示效果:

第二,ES2015模块化语法带有隐式的异步行为。

比如说,

A模块依赖于B、C模块。当用户请求A模块,JS模块加载器会先加载B和C模块,才能调用A模块。这里B和C模块都是异步加载的。

第三,典型的应用场景会给导出的内容起一个名字。

使用别名导入整个模块的DEMO:

import * as math from "./math";//as语法咯console.log(math.square(2));
console.log(math.log(100));

第四,默认导出。

模块导出使用了export default语法,是一种带名字的导出。

基本的默认导出DEMO:

math3.ts:

export default function cube(x){return Math.pow(x,3);//默认导出的名字是cube}
export function square(x){return Math.pow(x,2);
}

app3.ts:

import cube from "./math3";//等同于import {default as cube} from "./math3console.log(cube(3));

显示结果正常:

默认导出混合其他导出的DEMO:

math3.ts:

export default function cube(x){return Math.pow(x,3);//默认导出的名字是cube}
export function square(x){return Math.pow(x,2);
}
app4.ts:
import cube,{square} from "./math3";
console.log(square(2));
console.log(cube(3));

显示结果OK:

 (6)ES2015的模块加载器

通过编程的方式加载app模块执行main函数,使用System对象的import方法就好了。现在代码因为缺乏配置项,所以还运行不起来。

app.ts:

export function main(){
    console.log(2);
}

init.js

System.import("./app")
.then(app=>{
    app.main();
})
.catch(error=>{
   console.log("致命的错误"); 
});

四: 发挥静态类型的优势

有了静态类型,那么IDE开发环境除了避免输入错误的语法高亮,还提供精确静态分析的建议。很棒。

typescript的所有类型包含几类:

● 原生类型

● 组合类型

● Object类型

● 泛型

● any类型

(1)使用显式类型定义

除了webstorm报类型(type)错误,运行编译命令,typescript  也报错 Type 'string' is not assignable to type 'number' 。那么就是说,一旦foo设置了类型,就不能赋值为其他类型了。

(2)any类型

any类型是所有其他类型的父类,代表可以拥有任何类型的值,类似于动态类型,一方面不会报错,另一方面则放弃了typescript的优点了。

let foo:any;
foo={};
foo="bar";
foo+=24;
console.log(foo);//结果为"bar 24"。

(3)原生类型

就是javascript比较熟悉的Number、String、Boolean、Null、以及Undefined。而Enum是用户自定义的原生类型,它是Number的子类。含义是枚举用户自定义的类型,由一系列有名称的值也就是元素构成。

定义enum如下:

enum STATES{
    CONNECTING,
    WAITING,
    CONNECTED
}//定义枚举类型if(this.state==STATES.CONNECTING){//通过点语法引入}

(4)Object类型

首先,讲更加通用的Array类型,它是Object的子类。

Typescript的数组,要求元素类型相同。都可以使用js的各种数组方法,比如push、join、splice等,也可以使用方括号运算符对数组元素进行访问。

数值型数组DEMO:

let primes:number[]=[];
primes.push(2);
primes.push(3);
console.log(primes);

any型数组:

let randomItems:any[]=[];
randomItems.push(1);
randomItems.push("foo");
randomItems.push("{}");
console.log(randomItems);

屏幕结果为

第二,说Function类型,也是Object的子类哦。

javascript有两种方式创建新函数:

//函数表达式var isPrime=function(n){

}//函数声明function isPrime(n){
   
}//或者,使用箭头函数var isPrime=n=>{   //函数体}

Typescript增加的是参数和返回值的类型。

函数表达式:

let isPrime:(n:number)=>boolean=n=>{//整个函数赋给变量isPrime,参数是number类型的n,返回值是boolean类型的n,函数体在{}里面}

函数声明:

function isPrime(n:number):boolean{//参数为number类型,返回值为boolean类型}

对象字面量的定义写法:

let person={
     _name:null,
     setName(name:string):void{       //参数是string类型,返回值是void   this._name=name;
     }
}

(5)定义类

typescript定义类,属性的声明式强类型的。

 class-basic.ts:

class Human {
    static totalPeople=0;
    _name:string;//强类型的哦    constructor(name){      this._name=name;
      Human.totalPeople+=1;
    };
    get name(){return this.name;
    }
    set name(val){this._name=val;
    }
    talk(){return "HI,I'am"+this._name;
    }
}
let human=new Human("foo");
console.log(human._name);

打印结果为

成功

(6)访问修饰符

有3个。更好的实现封装和更优雅的接口。

●public。public的属性和方法在任何地方可以访问。

●private。private的属性和方法只能在类定义内部进行访问。

●protected。protected的属性和方法可以类定义内部访问,也可以从子类访问。

//typescript实现class Human{
    static totalPeople=0;
    constructor(protected name:string,private age:number){//定義了一個protected型的屬性,名為name,類型為string//age屬性。好處是避免显示式的赋值操作Human.totalPeople+=1;
    }
    talk(){return "Hi,I'm"+this.name;
    }
}
class Developer extends Human{
    constructor(name:string,private languages:string[],age:number){//显式使用访问修饰符,或者定义接收的参数类型,都可以混合使用的。        super(name,age);
    }
    talk(){return super.talk()+" And I Know "+this.languages.join('.');

    }
}//创建developer类的一个新实例let Dev=new Developer("foo",["javascript","Go"],42);//dev.languages=["java"];这行代码会报一个私有属性的错误let human=new Human("foo",42);//human.age=42;由于私有属性,所以报错//human.name="bar",会报一个protected错误。它只能在类类内部或者子类中访问

(6)接口

接口定义了一组对象共同的属性和方法,称作接口签名。要实现接口,那么实现定义接口规定的所有属性和方法。

关键字就2个,interface和implements。

interface Accountable1{
    goIncome():number;
    accountNumber:string
}
class Value implements Accountable1{
    constructor( public accountNumber:string){this.accountNumber=accountNumber;
    }
    goIncome():number{return 100;
    }
}var extra=new Value("余额");
console.log(extra.accountNumber);

打印为

接口实现,成功

接口继承

接口之间可以互相继承。接口继承另外一个接口,使用extends关键字。

interface-extends.ts:

interface Accountable2{
    accountNumber:string;
    getIncome():number;
}
interface Individual extends Accountable2{
    ssn:string;
}

实现多个接口:

interface People{
    age:number;
    name:string;
}
interface Accountable{
    accountNumber:string;
    goIncome():number
}
class Person implements People,Accountable{  //实现多个接口,用逗号分隔    age:number;
    name:string;
    accountNumber:string;
    constructor(age:number,name:string,accountNumber:string){

    }
    goIncome():number{return 10;
    }
}var person=new Person(10,"100","1000");

五: 使用类型参数编写泛型代码

 可以写类似java的泛型代码,好精彩!使用“”。能写出更简洁的代码来。

(1)使用泛型类

定义一组类型的class。

class Nodes<t> {
    value:T;
    left:Nodes<t>;
    right:Nodes<t>;
}
let numberNode=new Nodes<number>();

let stringNode=new Nodes<string>();

numberNode.right=new Nodes<number>();//类型匹配numberNode.value=42;//类型匹配//numberNode.value="42";报错,类型不匹配//numberNode.left=stringNode;报错,类型不匹配</number></string></number></t></t></t>

(2)使用泛型函数

定义一组类型的函数。

function identify<t>(arg:T){return arg;
}
interface Comparable{
    compare(a:Comparable):number;
}function sort<i>(arr:Comparable[]){//}</i></t>

(3)多重泛型

class Pair<k>{
    key:K;
    value:V;
}
let pair=new Pair<string>()
pair.key="foo";
pair.value=42;</string></k>

精彩

五: 使用typescript的类型推断机制简化代码

typescript可以猜测代码中的静态类型。好智能哦,所以可以用来省略一些代码。

let answer=42;
answer="42";//会提示错误,因为一开始的赋值,typescript已经把它当做number类型了。let answer;
answer=42;
answer="42";//这个时候不会报错,因为第一次声明时,typescript给到的静态类型是any。

(1)最常见的类型

let x=["42",42];//x的类型推断为any[]数组。
let x=[42.null,32];//typescript的类型推断为number[]。

(2)与上下文有关的类型推断

 

这里可以看到e并没有规定类型,可是typescript就根据上下文推断它为MouseEvent鼠标事件。

六: 使用外部类型定义

尽管静态类型很酷,但是我们使用的大部分前端类库都是基于javascript构建的,都是动态类型。而typescript提供了额外的类型定义,来给编译器提供提示。

(1)使用预定义的外部类型定义

 step1:安装typings工具

npm install  -g  typings

于是就安装好了typings目录,tsconfig.json、typings.json中,内容为:

//tsconfig.json{  "compilerOptions": {"module": "commonjs","target": "es5","sourceMap": true
  },  "exclude": ["node_modules"
  ]
}
//typings.json{  "dependencies": {}
}

step2:创建基础配置

typings init

step3:搜索

$  typings search module

step4:安装is-builtin-module

$  typings install is-builtin-module  --save

这个时候,typings.json的内容变为

{  "dependencies": {"is-builtin-module": "registry:npm/is-builtin-module#1.0.0+20161031191623"
  }
}

typings目录变为

(2)自定义外部类型

step1:定义好类库的接口。

define-external-type.ts:

interface LibraryInterface{
    selectElements(selector:string):HTMLElement[];
    hide(element:HTMLElement):void;
    show(element:HTMLElement):void;
}

step2:定义ts.d文件。

interface DOMLibraryInterface{
    selectElements(selector:string):HTMLElement[];
    hide(element:HTMLElement):void;
    show(element:HTMLElement):void;
}
declare var DOM:DOMLibraryInterface;

 step3:DOM通过reference引入,编译器就会找到对应的外部类型定义了。

///<reference></reference>var DOM={
    selectElements:function(selector:string):HTMLElement[]{return [];
    },
    hide:function(element:HTMLElement):void {
        element.hidden=true;
    }
};

这个时候,会报错。直到完全实现定义的接口为止,如下:

///<reference></reference>var DOM={
    selectElements:function(selector:string):HTMLElement[]{return [];
    },
    hide:function(element:HTMLElement):void {
        element.hidden=true;
    },
    show:function(element:HTMLElement):void{
        element.hidden=false;
    }
};

这样分离出来,就可以把全部的外部类型定义放在同一个文件里,方便管理了。

以上是typescript指南詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
使用Next.js(後端集成)構建多租戶SaaS應用程序使用Next.js(後端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

如何使用Next.js(前端集成)構建多租戶SaaS應用程序如何使用Next.js(前端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:22 AM

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript:探索網絡語言的多功能性JavaScript:探索網絡語言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

JavaScript的演變:當前的趨勢和未來前景JavaScript的演變:當前的趨勢和未來前景Apr 10, 2025 am 09:33 AM

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

神秘的JavaScript:它的作用以及為什麼重要神秘的JavaScript:它的作用以及為什麼重要Apr 09, 2025 am 12:07 AM

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

Python還是JavaScript更好?Python還是JavaScript更好?Apr 06, 2025 am 12:14 AM

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。1.Python以简洁语法和丰富库生态著称,适用于数据分析和Web开发。2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

如何安裝JavaScript?如何安裝JavaScript?Apr 05, 2025 am 12:16 AM

JavaScript不需要安裝,因為它已內置於現代瀏覽器中。你只需文本編輯器和瀏覽器即可開始使用。 1)在瀏覽器環境中,通過標籤嵌入HTML文件中運行。 2)在Node.js環境中,下載並安裝Node.js後,通過命令行運行JavaScript文件。

在Quartz中如何在任務開始前發送通知?在Quartz中如何在任務開始前發送通知?Apr 04, 2025 pm 09:24 PM

如何在Quartz中提前發送任務通知在使用Quartz定時器進行任務調度時,任務的執行時間是由cron表達式設定的。現�...

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器