TypeScript 那些事儿 01 变量类型 😊 let  变量名 : 变量类型 = valuefunction  ( 变量名:变量类型  ): 变量类型{}
数据类型 
类型 
例子 
描述 
 
 
number 
1,22,2.5 
任意数字 
 
string 
‘DuoR’,”bbb” 
任意字符串 
 
boolean 
true,false 
 
字面量 
其本身 
限制变量的值就是该字面量的值 
 
any 
* 
任意类型 
 
unknown 
* 
类型安全的 any 
 
void 
空值 undefined 
没有值 
 
never 
没有值 
不能是任何值 
 
object 
对象值 
js Object 
 
array 
[1,2,3,] 
js array 
 
tuple 
[4,5] 
元组,表示一个已知元素数量和类型的数组 
 
enum 
enum{A,B} 
枚举 
 
联合声明 
boolean | string 
可以是 boolean 和 string 类型 
 
变量类型之间是不可以互相赋值的,否则会报错
声明和赋值是同时进行的,TS 可以自动对类型进行检测,可以省略定义类型的步骤
类型断言,变量1 = <变量类型> 变量名2 或 变量1 = 变量名2 as 变量类型
类型的别名, type 自定义类型名 = 变量类型(|,&)
typescrpt 3.4 引入 readonly, 修饰后,变量只读:
 
const  arr : readonly string[]= ['1' ,'2' ,'3' ]
注意点: 
a. 在 tsconfig.json 指定了"strictNullChecks":false,undefined 与 null 是可以赋值到其他类型的(string/num…),否则,null 和 undefined 只能赋值给 void 和它们各自的类型。
b. number 和 bigint 都是表示数字,但是这两个类相互不兼容的
函数 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 function  sum (num1: number , num2: number  ): number  {return  num1 + num2sum (98 , 29 )let  sub = (num1 : number , num2 : number ): number  =>return  num1 - num2sub (98 , 29 )type  Types  = number  | string function  add (a: string , b: string  ): string function  add (a: number , b: number  ): number function  add (a: number , b: string  ): string function  add (a: string , b: number  ): string function  add (a: Types, b: Types ) {if  (typeof  a === 'string'  || typeof  b === 'string' ) {return  a.toString () + b.toString ()return  a + badd ('1' , '2' ).split ('' )
特别的类型 never 
表示的是那些永不存在的值的类型
 
两种情况:
function  err (msg: string  ): never  {throw  new  Error (msg)function  loopForever (never  {while  (true ) {}
特别用法:
type  Foo  = string  | number function  controlFlowAnalysisWithNever (foo: Foo ) {if  (typeof  foo === 'string' ) {else  if  (typeof  foo === 'number' ) {else  {const  check : never  = footype  Foo  = string  | number  | boolean 
unknown 
unknown与any的最大区别是: 任何类型的值可以赋值给any,同时any类型的值也可以赋值给任何类型。unknown 任何类型的值都可以赋值给它,但它只能赋值给unknown和any
 
function  getDogName (let  x : unknownreturn  xconst  dogName = getDogName ()const  upName = dogName.toLowerCase () if  (typeof  dogName === 'string' ) {const  upName = dogName.toLowerCase () const  upName = (dogName as  string ).toLowerCase () 
Number、String、Boolean、Symbol 
首先,我们来回顾一下初学 TypeScript 时,很容易和原始类型 number、string、boolean、symbol 混淆的首字母大写的 Number、String、Boolean、Symbol 类型,后者是相应原始类型的包装对象,姑且把它们称之为对象类型。
 
从类型兼容性上看,原始类型兼容对应的对象类型,反过来对象类型不兼容对应的原始类型。
下面我们看一个具体的示例:
let  num : number let  Num : Number Num  = num Num  
此,我们需要铭记不要使用对象类型来注解值的类型,因为这没有任何意义。 
object、Object 和 {} 
另外,object(首字母小写,以下称“小 object”)、Object(首字母大写,以下称“大 Object”)和 {}(以下称“空对象”)
 
小 object 代表的是所有非原始类型,也就是说我们不能把 number、string、boolean、symbol 等 原始类型赋值给 object。在严格模式下,null 和 undefined 类型也不能赋给 object。
let  lowerCaseObject : object 1  'a'  true  null  undefined  
大 Object 代表所有拥有 toString、hasOwnProperty 方法的类型,所以所有原始类型、非原始类型都可以赋给 Object。同样,在严格模式下,null 和 undefined 类型也不能赋给 Object。
let  upperCaseObject : Object 1  'a'  true  null  undefined  
综上结论:{}、大 Object 是比小 object 更宽泛的类型(least specific),{} 和大 Object 可以互相代替,用来表示原始类型(null、undefined 除外)和非原始类型;而小 object 则表示非原始类型。 
字面量 
在 TypeScript 中,字面量不仅可以表示值,还可以表示类型,即所谓的字面量类型。
 
let  specifiedStr : 'this is string'  = 'this is string' let  specifiedNum : 1  = 1 let  specifiedBoolean : true  = true 
应用场景:
比如声明如下所示的一个类型 Config:
interface Config  {size : 'small'  | 'big' ;isEnable : true  | false ;margin : 0  | 2  | 4 ;
需要注意 :
在缺省类型注解的情况下,TypeScript 推断出它的类型直接由赋值字面量的类型决定
const  str = 'this is string'  const  num = 1  const  bool = true  
02 ts 专业名词 🧐 类型推断 
在很多情况下,TypeScript 会根据上下文环境自动推断出变量的类型,无须我们再写明类型注解。
 
let  str : string  = 'I am a string' let  num : number  = 1 let  bool : boolean  = true let  str = 'I am a string' let  num = 1 let  bool = true 
我们把 TypeScript 这种基于赋值表达式推断类型的能力称之为类型推断
在 TypeScript 中,具有初始化值的变量、有默认值的函数参数、函数返回的类型都可以根据上下文推断出来。比如我们能根据 return 语句推断函数返回的类型,如下代码所示:
function  add1 (a: number , b: number  ) {return  a + bconst  x1 = add1 (1 , 1 ) function  add2 (a: number , b = 1  ) {return  a + bconst  x2 = add2 (1 )const  x3 = add2 (1 , '1' ) 
但!如果定义的时候没有赋值,不管之后有没有赋值,都会被推断成 any 类型而完全不被类型检查。
类型断言 TypeScript 类型检测无法做到绝对智能,毕竟程序不能像人一样思考。有时会碰到我们比 TypeScript 更清楚实际类型的情况,比如下面的例子:
const  arrayNumber : number [] = [1 , 2 , 3 , 4 ]const  greaterThan2 : number  = arrayNumber.find ((num ) =>  num > 2 ) const  arrayNumber : number [] = [1 , 2 , 3 , 4 ]const  greaterThan2 : number  = arrayNumber.find ((num ) =>  num > 2 ) as  number  
语法 let  str : string = "我是string" let  a : number = <number>str;let  a : number = str as  number;
非空断言 在上下文中当类型检查器无法断定类型时,可以使用 "!"断言操作对象非 null 或 undefined
let  str : null  | undefined  | string;toString () toString () Foo  = () =>  numberfunction  myFun (foo: Foo || undefined  ) {foo ();
确定赋值断言 允许在实例属性和变量声明后面放置一个 "!" 号,从而告诉 TypeScript 该属性会被明确地赋值。为了更好地理解它的作用,我们来看个具体的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 let  x : number;initialize ();console .log (2  * x); function  initialize (10 ;let  x!: number;initialize ();console .log (2  * x); function  initialize (10 ;
通过 let x!: number; 确定赋值断言,TypeScript 编译器就会知道该属性会被明确地赋值。
类型拓宽(Type Widening) 类型缩小(Type Narrowing) 03 编译选项 tsconfig.json💕 编译选项 include 示例: [path1,path2…]
作用:规定需要编译的路径
exclude 示例: [path1,path2…]
作用:排除规定不需要编译的路径
常见的编译选项:
选项 
类型 
默认 
描述 
 
 
target 
string 
“ES3” 
指定ECMAScript目标版本 
 
module 
string 
target === “ES6” ? “ES6” : “commonjs” 
指定生成哪个模块系统代码 
 
lib 
string[] 
编译过程中需要引入的库文件的列表。 
 
outDir 
string 
重定向输出目录。 
 
outFile 
string 
将输出文件合并为一个文件。 
 
removeComments 
boolean 
false 
编译后移除注释 
 
allowJs 
boolean 
false 
是否编译 js 文件 
 
checkJs 
boolean 
false 
在 .js文件中报告错误。与 --allowJs配合使用。 
 
noEmitOnError 
boolean 
false 
编译,但不生成编译后的文件 
 
noEmitOnError 
boolean 
false 
报错时不生成输出文件 
 
alwaysStrict 
boolean 
false 
以严格模式解析并为每个源文件生成 "use strict"语句 
 
noImplicitAny 
boolean 
false 
在表达式和声明上有隐含的 any类型时报错。 
 
03 使用 webpack 打包 ts 代码 📦 webpack 配置 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 const  path = require ('path' )const  HtmlWebpackPlugin  = require ('html-webpack-plugin' )const  { CleanWebpackPlugin  } = require ('clean-webpack-plugin' )module .exports  = {mode : 'development' ,entry : './src/index.ts' ,output : {filename : 'bundle.js' ,path : path.resolve (__dirname, 'dist' ),environment : {arrowFunction : false ,module : {rules : [test : /\.ts$/ ,use : [loader : 'babel-loader' ,options : {presets : ['@babel/preset-env' ,targets : {ie : 11 ,corejs : '3' ,useBuiltIns : 'usage' ,'ts-loader' ,exclude : /node_modules/ ,plugins : [new  CleanWebpackPlugin (),new  HtmlWebpackPlugin ((options = { template : './src/index.html'  })),devServer : {static : {directory : path.resolve (__dirname, 'public' ),port : 8081 ,resolve : {extensions : ['.ts' , '.js' ],