一、準備
1. 安裝
npm install -g typescript
2. vscode自動編譯
- 項目目錄終端執行
tsc --init
- 更改tsconfig.json “outDir”: “./js”
二、基礎語法
1.數據類型
- 布爾值
- 數字
- 字符串
- 數組
- 元組 Tuple
- 枚舉
- Any
- Void (函數沒有返回值使用。)
- Null 和 Undefined (默認情況下null和undefined是所有類型的子類型。)
- Never (never類型是任何類型的子類型)
- Object
2.函數
聲明函數
function run():string {
return 'typescript';
}
匿名函數
var fun = function():string {
return 'typescript';
}
定義方法傳參
function user(name:string,age:number):string {
return `${name}----${age}`;
}
var user = function(name:string,age:number):string {
return `${name}----${age}`;
}
沒有返回值
function run():void {
console.log('typescript' );
}
方法可選參數
function user(name: string,age?:number):string {
return `${name}----${age}`;
}
方法參數默認值
function user(name: string,age:number=20):string {
return `${name}----${age}`;
}
方法剩餘參數
function user(...result:number[]):string {
}
function user(name: string,...result:number[]):string {
}
重載
function user(name: string):string;
function user(age: number):number;
function user(str:any):any {
if(typeof str==='string) {
return str
} else {
return str
}
}
|
3.類
基本模型
class Person {
name: string; //屬性 省略publick 關鍵詞
constructor(name:string) { //構造函數 實例化的時候調用的方法(初始化對象)
this.name = name;
}
run():void {
alert(this.name);
}
}
class Person {
name: string; //屬性 省略publick 關鍵詞
constructor(name:string) { //構造函數 實例化的時候調用的方法(初始化對象)
this.name = name;
}
setName():void {
this.name = name;
}
getName():string {
alert(this.name);
}
}
var person1 = new Person('張三');
alert(person1.getName());
person1.setName('李四');
alert(person1.getName());
|
4.繼承
class Person {
name: string; //屬性 省略publick 關鍵詞
constructor(name:string) { //構造函數 實例化的時候調用的方法(初始化對象)
this.name = name;
}
run():string {
return `${this.name}`
}
}
子類可以使用父類的屬性和方法 如果子類的方法或者屬性和父類相同 則以子類為主
class Web extends Person {
constructor(name:string) {
super(name); //初始化父類的構造函數
}
work():string {
return `${this.name}在運動`
}
run():string {
return `${this.name}`
}
}
var w = new Web('李四');
alert(w.run());
|
5.類裏面的修飾符
共有類型 在類裏面、子類、類外面都可以訪問(默認,不寫默認就是)。
保護類型 在類裏面、子類可以訪問,類外面都不可以訪問。
私有類型 在類裏面可以訪問,子類和類外面都不可以訪問。
6.類的靜態屬性和靜態方法
- static (靜態方法裏面不能直接調用類裏面的屬性,能調用靜態屬性)
class Person {
public name:string;
static age:number=20;
constructor(name) {
this.name = name;
}
run() {
alert(`${this.name}在運動`);
}
static print() {
alert(`print`+Person.age);
}
}
|
7.多態
- 父類定義一個方法不去實現,讓繼承它的子類去實現,讓每一個子類有不同的表現
class Animal {
name:string;
constructor(name:string){
this.name = name;
}
eat() {
console.log('吃的方法');
}
}
class Dog extends Animal {
constructor(name:string) {
super(name)
}
eat() {
return this.name + '骨頭'
}
}
class Cat extends Animal {
constructor(name:string) {
super(name)
}
eat() {
return this.name + '魚'
}
}
|
8.抽象類
- 提供標準
- abstract 抽象類不能實例化 為子類提供基類
- 子類必須實現父類的抽象方法
- abstract必須放在抽象類裏面
abstract class Animal {
name:string;
constructor(name:string){
this.name = name;
}
abstract eat():any;
}
class Dog extends Animal {
constructor(name:any) {
super(name);
}
eat() {
console.log(this.name);
}
}
|
8.接口
- 定義規範 定義行為和動作的規範 (接口不關心類內部的數據狀態和方法實現的細節)
interface FullName {
firstName: string;
secondName: string;
}
function printName(name: FullName) {
console.log(name.firstName+ '--' +name.secondName)
}
var obj = {
firstName: 'sun',
secondName: 'yu'
}
printName(obj) // ok
接口的可選屬性
interface FullName {
firstName: string;
secondName?: string;
}
function printName(name: FullName) {
console.log(name.firstName+ '--' +name.secondName)
}
var obj = {
firstName: 'sun',
secondName: 'yu'
}
printName(obj) // ok
var obj = {
firstName: 'sun'
}
printName(obj) // ok
函數類型的接口
interface encrypt {
(key:string,value:string):string;
}
var md5:encrypt = function(key:string,value:string):string {
return key+value;
}
md5('key','value');
可索引接口 數組和對象的約束(不常用)
interface userArr {
[index:number]:string
}
var arr:userArr = ['string','string']; //ok
interface userObj {
[index:string]:string
}
var arr:userObj = ['string','string']; //ok
類類型接口 對類的約束
interface Animal {
name:string;
eat(str:string):void;
}
class Dog implements Animal {
name: string;
constructor(name:string) {
this.name = name;
}
eat() {
return `吃骨頭`;
}
}
var dog = new Dog('小黑');
dog.eat();
接口擴展 接口擴展接口
interface Animal {
eat():void;
}
interface Person extends Animal {
work():void;
}
class Web implements Person {
public name:string;
constructor(name:string){
this.name= name;
}
eat() {
console.log(this.name+'喜歡吃饅頭');
}
work() {
console.log(this.name+'愛工作');
}
}
---------------------------
interface Animal {
eat():void;
}
interface Person extends Animal {
work():void;
}
class programmer {
public: name:string;
constructor(name:string) {
this.name = name;
}
coding(code:string){
console.log(this.name+code);
}
}
class Web extends programmer implements Person {
constructor(name:string){
super(name)
}
eat() {
console.log(this.name+'喜歡吃饅頭');
}
work() {
console.log(this.name+'愛工作');
}
}
|
9.泛型
function getData<T>(value:T):T {
return value;
}
getData<number>(123);
function getData<T>(value:T):any {
return value;
}
getData<number>(123);
getData<string>('123');
泛型類
class MinClass<T> {
public list:T[]=[];
add(value:T):void {
this.list.push(value);
}
min():T{
var minNum = this.list[0];
for(var i=0;i<this.list.length;i++) {
if(minNum>this.list[i]) {
minNum = this.list[i];
}
}
return minNum;
}
}
var m1 = new MinClass<number>(); // 實例化類 並且制定類的T代表類型是number
m1.add(123);
var m2 = new MinClass<string>(); // 實例化類 並且制定類的T代表類型是string
m2.add('123');
泛型接口
interface ConfigFn {
<T>(value:T):T;
}
var getData:ConfigFn = function<T>(value: T):T {
return value;
}
getData<string>('張三');
getData<number>(123);
interface ConfigFn<T> {
<T>(value:T):T;
}
function getData<T>(value: T):T {
return value;
}
var myGetData:ConfigFn<string>=getData;
myGetData('張三');
var myGetDataw:ConfigFn<number>=getData;
myGetData(123);
把類作為參數來約束數據傳入類型
class User {
userName: string | undefined;
password: string | undefined;
}
class MysqlDb {
add(User:User):boolean {
console.log(User);
return true;
}
}
var user = new User();
user.userName = '張三';
user.password = '123456';
var db = new MysqlDb();
db.add(user);
泛型類
class User {
userName: string | undefined;
password: string | undefined;
}
class MysqlDb {
add(User:T):boolean {
console.log(User);
return true;
}
}
var user = new User();
user.userName = '張三';
user.password = '123456';
var db = new MysqlDb<User>();
db.add(user);
約束規範使用接口,代碼重用使用泛型。
interface DBI<T> {
add(info:T):boolean;
update(info:T,id:number):boolean;
delete(id:number):boolean;
get(id:number):any[];
}
class MysqlDb<T> implements DBI<T> {
add(info:T):boolean {
console.log(info);
return true;
}
update(info:T,id:number):boolean {
console.log(info,id);
return true;
}
delete(id:number):boolean {
console.log(id);
return true;
}
get(id:number):boolean {
console.log(id);
return true;
}
}
class Mongodb<T> implements DBI<T> {
add(info:T):boolean {
console.log(info);
return true;
}
update(info:T,id:number):boolean {
console.log(info,id);
return true;
}
delete(id:number):boolean {
console.log(id);
return true;
}
get(id:number):boolean {
console.log(id);
return true;
}
}
|
10.模塊
- 模塊的概念(官方): ”內部模塊“=》”命名空間“,”外部模塊“=》”模塊“ 模塊在其自身的作用域裏面執行,而不是在全局作用域執行。這就意味着定義一個模塊裏的變量,函數,類等等在模塊外部是不可見的,除非你明確的使用export形式之一導出他們。相反,如果想使用其他模塊導出的變量,函數,類,接口等的時候,你必須要導入它們,可以使用import形式之一。
- 模塊的概念(自己理解): 我們可以把一些公共的功能單獨抽離成一個文件作為一個模塊。模塊裏面的變量,函數,類等都是私有的,如果我們要在外部訪問模塊裏面的數據(變量,函數,類),我們需要通過export暴露模塊裏面的數據(變量、函數、類、、、)暴露後我們通過import引用模塊裏面的數據(變量,函數,類)。
定義 db.ts
var a:string = "string";
function getData(value:string):string {
return value
}
export {
a,
getData
}
使用
import { a,getDate } form './db'
getData();
import { a,getData as get} form './db'
get();
定義 db.ts
exprot default function getData(value:string):string {
return value
}
使用
import getData form './db'
getData();
|
11.命名空間
- 命名空間和模塊的區別: 命名空間,內部模塊,主要用於組織代碼,避免命名衝突。 模塊,ts的外部模塊的簡稱,側重代碼的複用,一個模塊裏可能會有多個命名空間。
namespace A {
interface Animal {
name:string;
eat(str:string):void;
}
export class Dog implements Animal {
name: string;
constructor(name:string) {
this.name = name;
}
eat() {
return `吃骨頭`;
}
}
}
var dog = A.Dog("小黑");
dog.eat();
命名空間封裝成模塊
a.ts文件名
定義
export namespace A {
interface Animal {
name:string;
eat(str:string):void;
}
export class Dog implements Animal {
name: string;
constructor(name:string) {
this.name = name;
}
eat() {
return `吃骨頭`;
}
}
}
使用
import { a } from './a'
var dog = new a.Dog();
dog.eat();
|
12.裝飾器
- 裝飾器: 裝飾器是一種特殊類型的聲明,它能夠被附加到類聲明,方法,屬性或參數上,可以修改類的行為。
- 通俗的講裝飾器就是一個方法,可以注入到類、方法、屬性參數上來擴展類、屬性、方法、參數的功能。
- 常見的裝飾器有: 類裝飾器、屬性裝飾器、方法裝飾器、參數裝飾器。
- 裝飾器寫法: 普通裝飾器(無法傳參)、裝飾器工廠(可傳參)。
- 裝飾器是過去幾年中js最大的成就之一,已經是Es7的標準特性之一。
1.類裝飾器(普通裝飾器,無法傳參)
function logClass(params:any){
console.log(params);
params.prototype.apiUrl="動態擴展的屬性";
params.prototype.run = function() {
console.log("我是run方法");
}
}
@logClass
httpClient {
constructor() {
}
getData() {
}
}
var H = new httpClient();
console.log(H.apiUrl);
H.run();
2.類裝飾器(裝飾器工廠,可傳參)
function logClass(params:string){
return function(target:any) {
target.prototype.apiUrl="動態擴展的屬性";
target.prototype.run = function() {
console.log("我是run方法");
}
}
}
@logClass('hello')
httpClient {
constructor() {
}
getData() {
}
}
把類賦值給target
把參數賦值給params
var H:any = new httpClient();
console.log(H.apiUrl);
H.run();
類裝飾器重載以前類的構造函數
function logClass(target: any) {
console.log(target);
return class extends target{
apiUrl:any = "我是修改後的url";
getData() {
console.log(this.apiUrl);
}
}
}
@logClass
httpClient {
public apiUrl: string | undefined;
constructor() {
this.apiUrl = 'url';
}
getData() {
console.log(this.apiUrl);
}
}
var http = new httpClient();
------------------------------
3.屬性裝飾器(屬性裝飾器表達式會在運行時當作函數調用,傳入下列兩個參數,對於靜態成員來説是類的構造函數,對於實例成員是類的原型對象)
function logClass(params:any){
console.log(params);
params.prototype.apiUrl="動態擴展的屬性";
params.prototype.run = function() {
console.log("我是run方法");
}
}
function logProperty(params:string){
return function(target: any,attr:any) {
console.log(target);
console.log(target[attr]);
target[attr] = params;
}
}
@logClass('xxx')
httpClient {
@logProperty("http://baidu.com");
public url: string | undefined;
constructor() {
}
getData() {
console.log(this.url);
}
}
var http = new httpClient();
http.getData();
4.方法裝飾器
它會被應用到的方法的屬性描述符上,可以用來監視,修改或者替換方法定義
方法裝飾器會在運行是傳入下列3個參數
(1)對於靜態成員來説類的構造函數,對於實例成員來説是類的原型對象。
(2)成員的名字。
(3)成員的屬性描述符。
function logMethod(params: any) {
return function(target:any,methodName:any,desc:any) {
console.log(target);
console.log(methodName);
console.log(desc);
target.apiUrl="動態擴展的屬性";
target.run = function() {
console.log("我是run方法");
}
}
}
httpClient {
constructor() {
}
@logMethod("http://baidu.com")
getData() {
console.log(this.url);
}
}
var http:any = new httpClient();
http.run();
------------------------------------------
function logMethod(params: any) {
return function(target:any,methodName:any,desc:any) {
console.log(target);
console.log(methodName);
console.log(desc);
//修改裝飾器的方法 把裝飾器方法傳入所以參數改為string類型
//保存當前的方法
var oMethod = desc.value;
desc.value = function(...args:any[]) {
args = args.map((value)=>{
return String(value)
});
console.log(args);
}
}
}
httpClient {
public url:any | undefined;
constructor() {
}
@logMethod("http://baidu.com")
getData() {
console.log(this.url);
}
}
var http:any = new httpClient();
http.getData(123,'xxx');
|
本文章為轉載內容,我們尊重原作者對文章享有的著作權。如有內容錯誤或侵權問題,歡迎原作者聯繫我們進行內容更正或刪除文章。