tsc、TypeScript编译器 在终端安装typescript:
安装完成后可以使用tsc
命令来执行typescript的相关代码。
在vscode新建一个index.ts,输入一下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 let a : stringlet b : numberlet c : booleana = 'hello' b = 99 c = true console .log (a, b, c)function count (x: number, y: number ): number { return x + y } let result = count (1 , 2 )console .log (result)let srt1 : string srt1 = 'youxianyu' console .log (typeof srt1)
直接使用浏览器是不认识的,需要用tsc
命令转换为javascript代码:
1 2 tsc --watch tsc --watch index.ts
转换后index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 "use strict" ;let a;let b;let c;a = 'hello' ; b = 99 ; c = true ; console .log (a, b, c);function count (x, y ) { return x + y; } let result = count (1 , 2 );console .log (result);let srt1;srt1 = 'youxianyu' ; console .log (typeof srt1);
使用index.js
1 2 3 4 5 6 7 8 9 10 11 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > index</title > </head > <body > <script type ="text/javascript" src ="./index.js" > </script > </body > </html >
成功
常用类型 any any的含义量:任意类型,一旦将变量类型限制为any,那就意味着放弃了对该变量的类型检查。
1 2 3 4 5 6 7 8 9 10 11 let an : any an = 91 an = 'hello' an = false let as : any as = 92 as = 'world' as = true
注意:any类型的变量,可以赋值给任意类型的变量
unknown unknown的含义是:未知类型。
1.unknown可以理解为一个类型安全any,适用于:不确定数据的具体类型。
1 2 3 4 5 6 7 8 9 let un : unknown un = 99 un = false un = 'hello' let x : string x = un
2.unknown会强制开发者在使用之前进行类型检查,从而提供更强的类型安全性。
1 2 3 4 5 6 7 8 9 10 11 12 let un : unknown un = 99 un = false un = 'hello' if (typeof un === 'string' ) { x=un } x = un as string x=<string >un
3.读取any类型数据的任何属性都不会报错,而unknown正好与之相反。
never never的含义是:任何值都不是,简而言之就是不能有值(什么都不行) 1.几乎不用never去直接限制变量,因为没有意义。
1 2 3 4 5 6 7 let a : never a=1 a=true a=undefined a=unll
2.never一般是typescript主动推断出来的。
1 2 3 4 5 6 7 8 let a : string a='hello' if (typeof a ==== 'string' ){ console .log (a.toUpperCase ()) }else { console .log (a) }
3.never也可用于限制函数的返回值。
1 2 3 function throwError (str: string ): never { throw new Error ('程序异常退出' +str) }
void void通常用于函数返回值声明,含义【函数不返回任何值,调用者也不应该依赖其返回值进行任何操作】
1 2 3 4 function logMessage (msg: string ): void { console .log (msg) } logMessage ('youxianyu' )
注意:logMessage函数是没有显示返回值的,但会有一个隐式返回值,就是undefined;记:undefined是viod可以接受的一种“空”。
1 2 3 4 5 6 7 8 9 10 11 function logMessage (msg: string ): void { console .log (msg) } function logMessage1 (msg: string ): void { console .log (msg) return ; } function logMessage2 (msg: string ): void { console .log (msg) return undefined }
总结:若函数返回值类型为void,那么: 1.从语法上讲:函数是可以返回undefined的,至于显示返回,还是隐式返回,这都无所谓! 2.从语义上讲:函数调用者不应关心函数返回的值,也不应依赖返回值进行任何操作及时返回了undefined值。
object 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 let o : object o = {} o = { name : 'tom' } o = [1 , 35 , 453 , 23 , 3 ] o = function ( ) { } o = new String ('123' ) class Person { }o = new Person () a = 1 a = ture a = 'you' a = null a=undefined
Object除了undefined和null的任何值。
声明对象类型 1.实际开发中,限制一般对象,通常使用以下形式。
1 2 3 4 5 6 7 8 let person1: { name: string , age?: number }let person3: { name: string ; age?: number }let person2: { name: string , age?: number } person1={name:'tom' ,age:19 }
2.索引签名:允许定义对象可以具有任意数量的属性,这些属性的键和类型是可变的,常用于:描述类型不确定的属性。(具有动态属性的对象)
1 2 3 4 5 6 7 8 9 10 11 let person:{ name:string age?:number [key:string ]: any } person={ name:'youxianyu' , age:18 , gender:'男' }
声明函数类型 1 2 3 4 let count :(a:number ,b:number )=> number count = function (x,y )=>{ return x+y }
TypeScript中的=>在函数类型声明表示函数类型,描述其参数类型和返回值类型。 JavaScript中的=>是一种定义函数的语法,是具体的函数实现。 函数类型声明还可以使用L:接口,自定义类型等方式。
声明数组类型 1 2 3 4 5 let arr1 :string []let arr2 :Array <string > arr1=['a' ,'b' ,'c' ] arr2=['hello' ,'world' ]
tuple 元组(tuble)是一种特殊的数组类型,可以存储固定数量的元素,并且每个元素类型是已知的且可以不同,元组用于精确描述一组值的类型,?表示可选元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 let arr1=[string ,number ]let arr2=[number ,boolean ?]let arr3=[number ,...string []]arr1=['hello' ,123 ] arr2=[100 ,flase] arr2=[200 ] arr3=[100 ,'hello' ,'world' ] arr3=[100 ] arr1=['hello' ,123 ,false ]
enum 枚举(enum)可以定义一组命名常量,他能增强代码的可读性,也让代码更好维护。
如下代码的功能是:根据调用walk时传入的不同参数,执行不同的逻辑,存在的问题是调用walk时传参时没有任何提示,编码者很容易写错字符串内容;并且用于判断逻辑的up、down、left、right是连续且相关的一组值,那此时就特别适合使用枚举(enum)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function walk (str: string ) { if (str === 'up' ) { console .log ('ok' ) } else if (str === 'down' ) { console .log ('sk' ) } else if (str === 'left' ) { console .log ('kn' ) } else if (str === 'right' ) { console .log ('kn' ) } } walk ('up' )walk ('ok' )walk ('left' )walk ('right' )
1.数字枚举 数字枚举一种最常用的枚举类型,其成员的值会自动递增,且数字枚举还具备反向映射的特点,在下面代码的打印中,可以通过只来获取对应的枚举成员名称。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 enum Direction { up, down, left, right } function walk (str: Direction ) { if (str === Direction .up ) { console .log ('ok' ) } else if (str===Direction .down ) { console .log ('sk' ) } else if () {str===Direction .left console .log ('kn' ) } else if (str === Direction .right ) { console .log ('kn' ) } } walk (Direction .down )
2.字符串枚举
1 2 3 4 5 6 7 8 enum pirection{ up='up' , down='down' , left='left' , right='right' } let dir :Direction =Direction .up console .log (dir)
3.常量枚举
1 2 3 4 5 6 7 const enum Directions { up, down, left, right } let x=Directions .up ;
type type可以为任意类型创建别名,让代码更简洁、可读性更强,同时能更方便地进行类型复用和扩展。 1.基本用法 类型别名使用type关键字,type后跟类型名称
1 2 3 type num=number ;let price :numprice=100
2.联合类型 联合类型是一种高级类型,他表示一个值可以是几种不同类型之一
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 type Status = number | string type Gender = '男' | '女' function printstatus (string Status ){ console .log (status); } function logGender (str:Gender ){ console .log (str) } printstatus (404 )printstatus ('200' )printstatus ('501' )logGender ('男' )logGender ('女' )
3.交叉类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 type Area = { height : number width :number } type Address = { num : number cell : number room :string } type House = Area & Address const house : House = { height : 100 , width : 120 , num : 3 , cell : 4 , room : '702' }
复习类相关知识 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Person { name : string age : number constructor (name: string , age: number ) { this .name = name this .age = age } speak ( ) { console .log (`我叫:${this .name} ,今年${this .age} 岁` ) } } const p1 = new Person ('YOUXIANYU' , 19 )console .log (p1)p1.speak () class Student extends Person { grade : string constructor (name: string , age: number , grade: string ) { super (name, age) this .grade =grade } study ( ) { console .log (`${this .name} ` ) } override speak ( ) { console .log (`我是学生:${this .name} ,今年${this .age} 岁${this .grade} ` ) } } const s1 = new Student ('youxianyu' , 19 , '大一' )console .log (s1)s1.study () s1.study ()
简写
1 2 3 class Person { constructor (public name:string , public age: number ) }
抽象类 抽象类是一种无法被实例化的类,专门用来定义类的结构和行为,类中可以写抽象方法,也可以写具体实现。抽象类主要用来为其派生类提供一个基础结构,要求其派生类必须实现其中的抽象方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 abstract class Package { constructor (public weight: number ) { } abstract calculate (): number printPackage ( ) { console .log (`${this .weight} ,${this .calculate()} ` ) } } class StandardPackage extends Package { constructor (weight: number , public unitPrice: number ) { super (weight) } calculate (): number { return this .weight *this .unitPrice } } class ExpressPackage extends Package { constructor (weight: number , public unitPrice: number , public additional: number ) { super (weight) } calculate (): number { if (this .weight > 10 ) { return 10 *this .unitPrice +(this .weight -10 )*this .additional }else { return this .weight *this .unitPrice } } } const s2 = new StandardPackage (10 , 50 )s2.printPackage () const s3 = new ExpressPackage (10 , 30 , 7 )s3.printPackage ()
总结:何时使用抽象类 1.定义通用接口:为一组相关的类定义通用的行为(方法或属性)时。 2.提供基础实现:在抽象类中提供某些方法或为其提供基础实现,这样派生类就可以继承这些实现。 3.确保关键实现:强制派生实现一些关键行为。 4.共享代码和逻辑:当多个类需要共享部分代码时,抽象类可以避免代码重复。
interface 定义类结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 interface PersonInterface { name : string age : number speak (n :number ):void } class Person1 implements PersonInterface { constructor (public name: string , public age: number ) { } speak (n : number ): void { for (let i = 0 ; i < n; i++){ console .log (`${this .name} ,${this .age} ` ) } } } const p2 = new Person1 ('youxianyu' , 19 )p2.speak (4 )
定义对象结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 interface UserInterface { name : string readonly gender : string age?: number run : (n: number ) => void } const user : UserInterface = { name : 'you' , gender : '男' , age : 19 , run (n ) { console .log (`${n} ` ) } }
定义函数接口
1 2 3 4 5 6 7 interface CountInterface { (a : number ,b : number ): number } const count : CountInterface =(x,y )=> { return x+y }
泛型 泛型函数
1 2 3 4 5 6 function logData<T>(data : T) { console .log (data) } logData<number >(100 ) logData<string >('you' )
多个泛型
1 2 3 4 5 6 7 function logData<T,U>(data1 : T,data2 :U): T | U{ console .log (data1,data2) return Data .now () % 2 ? data1 :data2 } logData<number ,boolean >(100 ,true ) logData<string ,number >('you' ,666 )
泛型接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 interface PersonInterface <T>{ name : string , age : number , extraInfo :T } type JobInfo = { title : string company :string } let p : PersonInterface <JobInfo >={ name :'you' , age : 19 , extraInfo : { title : '程序员' , company :'加油' } }
泛型类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Person <T>{ constructor ( public name: string , public age: number , public extraInfo: T ) { } speak ( ) { console .log (`${this .name} ${this .age} ` ) console .log (this .extraInfo ) } } type JobInfo = { title : string company :string } const p1 = new Person <JobInfo >('you' , 19 , {title :'xian' ,company :'okoko' })
装饰器 类装饰器 基本语法 1 2 3 4 5 6 7 8 9 10 11 12 13 function Demo (target: Function ) { console .log (target) } @Demo class Person { name : string age : number constructor (name: string , age: number ) { this .name = name this .age =age } }
应用实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 function CustomString (target: Function ) { target.prototype .toString = function ( ) { return JSON .stringify (this ) } } @CustomString class Person { name : string age : number constructor (name: string , age: number ) { this .name = name this .age =age } } const p1 = new Person ('you' , 19 )console .log (p1.toString ())
关于构造类型 声明构造类型
1 2 3 type Constructor = new (...args :any [])=>{}function test (fn:Constructor ){}test (Person )
声明构造类型+指定静态属性