Typescript 01-安装 Typescript
安装Typescript
1 2 3 4 5 6 7 8 9 npm install -g typescript # 或者使用cnpm进行安装 cnpm install -g typescript tsc -v 检测是否安装成功 初始化tsc --init tsc -w 可以自动编译 ts文件 我们只需要执行对应的js文件就可以了 tsc -ts文件名 将ts文件转义成js文件,ts文件不能直接运行,需要先转义成js
其他工具:
npm i @types/node -D ts-node ts文件名可以直接输出
npm i ts-node -g
npm i nrm -g 管理npm 镜像源
nrm -h 查看命令
nrm ls 查询镜像源 nrm use 镜像源
02-数据类型
布尔类型(boolean)
数字类型(number)
字符串类型(string)
数组类型(array)
对象类型(object)
元组类型(tuple)
枚举类型(enum)
任意类型(any)
null 和 undefined
void类型
never类型
number 1 2 3 4 5 6 7 let num : number = 2 let notnumber : number = NaN let infinityNumber : number = Infinity let decimal : number = 6 let hex : number = 0xf00d let binary : number = 0b1010 let octal : number = 0o744
boolean 1 2 let b1 : boolean = false let b2 : boolean = true
string
null undefined 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 let n : null = null let u : undefined = undefined n = u u = n 严格模式 tsconfig.json "strict" : true ,关闭严格模式 null 和 undefined 可以互相赋值 var num : number | undefined | null var a :number | string = 123 a = 'abc'
never 表示一中永远无法到达的类型 :type A = string & number // A 就是never类型
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 36 37 38 39 40 41 42 43 44 45 var a :undefined a = undefined var b :null b = null var c :neverc = (() => { throw new Error ('错误' ) })() function infiniteLoop ( ):never { while (true ){ } } type B = string | void | never type Kun = '唱' | '跳' | 'rap' | '篮球' function fn (value: Kun ) { switch (value) { case '唱' : break case '跳' : break case 'rap' : break case '篮球' : break default : const error :never = value break } }
void 类型 1 2 3 4 5 6 7 function run ( ):void { console .log ('run' ) } let unusable : void = undefined
Symbol类型 Symbol 表示唯一值,每个Symbol 数据都是唯一的
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 let a1 :symbol = Symbol (1 )let a2 :symbol = Symbol (1 )console .log (a1,a2) a1 === a2 a1 == a2 console .log (Symbol .for ('1' ) === Symbol .for ('1' )) let a1 :symbol = Symbol (1 )let a2 :symbol = Symbol (1 )let obj = { name : 1 , [a1]: 111 , [a2]: 222 , name : 80 } for (let key in obj){ console .log (key) } console .log (Object .keys (obj)) console .log (Object .getOwnPropertyNames (obj)) console .log (Object .getOwnPropertySymbols (obj)) console .log (Reflect .ownKeys (obj))
03-any 和 unknow 的区别 类型级别
顶级类型 any unknow
Object
Number String Boolean
number string boolean symbol null undefined
1 ‘张三’ false
never
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 var num :any = 123 num = true num = 'abc' let a : unknown = 1 let b : number = 2 let c : any = 3 b = a c = a let obj : unknown = { name : '张三' , setname : () => 123 } console .log (obj.name )
总结:
any类型可以赋给任意类型的值
unknown 只能赋值给自身 或者是 any
unknown 没有办法读取对象的任何属性,方法也不能调用
unknown 类型比 any 类型更加安全
04-Object object {} Object大写
1 2 3 4 5 6 7 let a :Object = '123' let a1 :Object = 123 let a2 :Object = false let a3 :Object = [] let a4 :Object = {} let a5 :Object = ()=> 123
object小写
1 2 3 4 5 6 7 let a :object = '123' let a1 :object = 123 let a2 :object = false let a3 :object = [] let a4 :object = {} let a5 :object = ()=> 123
{} 字面量
1 2 3 4 5 6 7 8 9 10 11 let a :{} = '123' let a1 :{} = 123 let a2 :{} = false let a3 :{} = [] let a4 :{} = {} let a5 :{} = ()=> 123 let b :{} = {name :'张三' }b.age = 25
05-interface接口 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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 interface msg { name : string age : number } interface msg { gender : string } let a : msg = { name : '张三' , age : 88 , gender : '男' } interface data { name : string age : number [propName :string]:any } let res :data = { name : '张三' , age : 88 , a :1 , b :2 , c :3 } interface a extends b { name : string } interface b { age : number } let obj :a = { name : '张三' , age : 88 , } interface Fn { (name :string):number[] } const fn :Fn = function (name:string ) { return [1 ] }
06-可选参数 1 2 3 4 5 6 7 8 9 interface msg { name : string age?: number } let a = { name :'zs' , age :10 }
07-readonly 1 2 3 4 5 interface msg { name : string age?: number readonly fn :()=> false }
08-数组的定义 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 36 37 var arr :number[] = [12 , 5 , 8 ] var arr :Array <number> = [12 , 5 , 8 ]let arr :any = [12 , "abc" ,"123" ]let arr :[number, string, string] = [12 , "abc" ,"123" ]interface obj { name :string age?:number } const arr :obj = [ {name :'张三' ,age :28 }, {name :'李四' } ] var arr :number[][] = [[12 ], [5 ], [8 ]] var arr :Array <Array <number>> = [[12 ], [5 ], [8 ]] function (...args:string[] ) { let a :any[] = arguments let a :A = arguments let a :IArguments = arguments } a ('1' ,'2' ) interface A { callee :Function length :number [index :number]:any }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 enum Flag {success = 1 , error = 2 } enum Direction { Up = 1 , Down , Left , Right } let s :Flag = Flag .success console .log (s) enum Color {blue, red, yellow = 3 , green, 'white' } console .log (Color .blue ) console .log (Color .red ) console .log (Color .yellow ) console .log (Color .green ) console .log (Color .white )
09-函数
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 function add (a: number,b: number ):number { reutrn a+b } console .log (add (1 ,1 )) const add = (a : number,b : number):number => a+bconsole .log (add (1 ,2 )) const add = (a : number = 10 ,b : number = 20 ):number => a+bconst add = (a : number = 1 ,b?: number):number => a+binterface user { name : number[], add : (this :obj,num:number ) => void } let obj = { name : [1 ,2 ,3 ], add (this :obj,num:number ) { this .user .push (num) } } obj.add (4 ) console .log (obj.user ) let arr : number[] = [1 , 2 , 3 ]function findNum (add:number[] ):number[] function findNum (id:number ):number[] function findNum ( ):number[] function findNum (ids?: number | number[] ): number[] { if (typeof ids === 'number' ) { return arr.filter (item => item == ids) } else if (Array .isArray (ids)) { arr.push (...ids) return arr } else { return arr } } console .log (findNum ([11 ]))
9-类型断言 | 联合类型 |交叉类型
当自己知道某个变量的类型时,可以通过类型断言这种方式告诉编译器。类型断言好比其他语言中的类型转换,但是不进行特殊的数据检查和结构,它没有运行时影响,只在编译阶段起作用。
!! 类型强转
!1 -> false ->!false -> true !!1 -> true
1 2 3 4 5 6 7 8 let fn = function (type: number | boolean ):boolean { return !!type } let result = fn (false )console .log (result)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 interface person { name :string, age :number } interface Man { sex :number } const fn = (man : person & Man ): void => { console .log (man) } fn ({ name : '张三' , age : 20 , sex : '男' })
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 let fn = (num: number | string ) => { console .log ((num as string).length ) } fn ('123' )interface A { run : string } interface B { bulid : string } let o = (type :A | B):void => { console .log ((<A>type).run ) } o ({run :'1' })window .a =123 (window as any).a = 123 const fn = (type :any):void { return type as boolean } console .log (fn (1 ))
10-内置对象 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 let num :Number = new Number (1 )let data :Date = new Date ()let reg :RegExp = new RegExp (/\w/ )let error :Error = new Error ('错误' )let xhr :XMLHttpRequest = new XMLHttpRequest ()let div :HTMLDivElement = document .querySelector ('div' )let div :NodeList = document .querySelectorAll ('div' )let div :NodeListof <HTMLDivElement | HTMLElement > = document .querySelectorAll ('div' )let local :Storage = localStorage let lo :Location = locationlet cookie :string = doucment.cookie let promise :Promise <number> = new Promise ((r )=> r (1 ))promise.then (res => { res. }) let promise :Promise <string> = new Promise ((r )=> r (1 ))promise.then (res => { res. })
11-类型推论 | 类型别名 类型推论
1 2 3 4 5 6 7 let str = '张三' str = 345 let arr = [1 ] let a a = 123 a = null
类型别名
1 2 3 4 5 6 7 8 9 10 type fn = () => void type o = {name :'张三' } type s = string type narr = number :[] type num = 1 extends number ? 1 :0
12-生成器 | 迭代器 生成器
1 2 3 4 5 6 7 8 9 10 function * gen ( ) { yield Promise .resolve (1 ) yield 2 } const man = gen ()console .log (man.next ()) console .log (man.next ()) console .log (man.next ())
迭代器
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 36 37 38 39 40 41 42 43 44 45 46 47 set map arr NodeList (dom节点) 等这些都是 有迭代器的 可以通过 [Symbol .iterator ]()获取 const set :Set <number> = new Set ([1 ,2 ,3 ])const each = (value:any ) => { let It :any = value[Symbol .iterator ]() let next :any = {done :false } while (!next.done ) { next = It .next () if (!next.done ) { console .log (next.value ) } } } each (set) for (let value of set) { console .log (value) } let obj = { max :5 , current :0 , [Symbol .iterator ](){ return { max :this .max , current :this .current next ( ) { if (this .current == this .max ) { return { value :undefined done :true } }else { return { value :this .current ++ done :false } } } } } } let x = [...obj] let y = {...obj}console .log (x) console .log (y)
13-泛型 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 36 37 38 39 40 41 42 43 44 45 46 47 function A (a:number, b:number ):Array <number>{return [a,b]}function B (a:number, b:number ):Array <number>{return [a,b]}function fn<T>(a :T, b :T):Array <T> { return [a, b] }fn (1 ,2 ) fn ('1' ,'2' ) type A<T> = string | number | T type a :A<null > = null iterface Data <T> = { msg :T, } let data :Data <number> = { msg :1 } function add<K, T>(a : K, b : T): Array <K | T> { return [a, b] } add (1 , false )const axios = { get<T>(url :string):Promise { return new Promise ((resolve,reject )=> { let xhr :XMLHttpRequest = new XMLHttpRequest () xhr.open ('GET' ,url) xhr.onreadystatechage = () => { if (xhr.readyState === 4 && xhr.status == 200 ){ resolve (JSON .parse (xhr.responseText )) } } xhr.send (null ) }) } } axios.get ('./data.json' ).then (res => { console .log (res) }) { "message" :"success" , "code" :200 }
14-泛型约束 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 36 37 38 39 40 function add<T extends number> (a :T,b :T) { return a + b } console .log (add (2 ,3 )) interface len { length :number } function fn<T extends len>(a :T) { console .log (a.length ) } fn ('111' )fn ([1 ,2 ,3 ])fn (false ) fn (111 ) let obj = { name : '张三' , sex : '男' } type key = keyof typeof obj function ob<T extends object, K extends keyof T>(obj : T, key : K) { return obj[key] } ob (obj, 'name' )interface Data { name :string, age :number, sex :string } type Options <T extends object> = { readonly [key in keyof T]?: T[key] } type c = Options <Data >
ts.config 配置文件 ts 命名空间污染 如果模块中没有带有 import 和 export声明 那么它的内容就是全局可见的(因此模块也是全局可见的)
1 2 3 4 5 6 const a = 1 const a = 2 export const a = 2
命名空间
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 namespace A { export const a = 1 } namespace B { export const a = 2 } namespace A { export namespace C { export const D = 5 } } console .log (A.C .D )export namespace B { export const a = 2 } import {B} from './B' console .log (A.C .D ,B)import AA = A.C console .log (AA .D )
多个命名空间
1 2 3 4 5 6 7 8 9 10 11 12 namespace A { export const a = 1 } namespace A { export const b = 2 } namespace A { export const a = 1 export const b = 2 }
三斜线指令
声明文件 在ts项目中要使用第三方包就必须下载对应的声明文件,如果没有就会报错
一种是直接去社区找对应的包的ts声明文件 @types/包名
一种是自己手动写一个声明文件 规范 包名.d.ts
Mixins混入 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 interface Name { name : string } interface Age { age : number } interface Sex { sex : string } let a : Name = { name : '张三' }let b : Age = { age : 23 }let c : Sex = { sex : '男' }let MixisObj = Object .assign (a, b, c)