第一章:TypeScript快速入门
阅读原文时间:2023年07月08日阅读:1

1、TypeScript 是什么?

TypeScript 是一种由微软开发的自由和开源的编程语言。它是 JavaScript 的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。

下图显示了 TypeScript 与 JavaScript、 ES5、ES2015 和 ES2016 之间的关系:

意思是:JavaScript 和 ES 有的,TypeScirpt都有!

2、TypeScript 与 JavaScript 的区别

3、TypeScript有什么用

  • 编译时的强类型

  • 模块化

  • 已有的类库可以很方便的使用

4、下载Node.js

  • 版本号 LTS:稳定版(一般开发下载这个)

  • 版本号 Current:最新版

5、安装Node.js

  • 找到下载的目录里面,打开Node.js进行无脑安装,直接下一步

  • 怎么知道安装成功?

  • 第一种方法:win + R 打开运行对话框,输入cmd 打开命令提示符窗口,输入node -v 回车 显示安装版本号,如以下结果即为成功!

  • 第二种方法:win 搜索powerShell,打开PowerShell 也是一样的输入node -v 回车 显示版本号,即为成功!

      

      

6、使用npm(node包管理器,通过这个可以安装node下面的各种应用与软件,下载完node.js就可以直接使用npm了)全局安装TypeScript

  • 进入命令行

  • 输入:npm i -g typescript

  • 显示以上信息,反正没有报错就表示typescript就已经安装好了
  • 怎么查看它有没有安装好呢?输入tsc 命令回车,如果出现一堆东西那就表示安装成功了,否则就显示没有找到这条命令。  

7、创建一个ts文件

  • 在任意一个文件夹里面新建一个后缀名为.ts的文件,用记事本或随意一个文本编辑器打开文件,输入console.log(' hello TS!');
  • 但是网页不认识ts文件怎么办?利用我们刚刚下载好的typescript编译器,把ts文件转化为js文件
  • 怎么转?使用tsc命令对ts文件进行编译

8、使用tsc对ts文件进行编译

  • 在所在文件夹里面输入cmd,在这里输入cmd的好处就是 命令行所在的路径正好就是当前所在文件的路径,就不用使用命令进入了! 

  • 输入命令:tsc 需要编译的文件名,回车执行,虽然命令提示符窗口没有发生什么变化,但是此时此刻你会发现该文件夹里面多了一个js文件!

1、类型分类:

JavaScript 的类型分为两种:原始数据类型(Primitive data types)和对象类型(Object types);

原始数据类型包括:布尔值、数值、字符串、null、undefined 以及 ES6 中的新类型 **Symbol
**

2、类型声明

  • 类型声明是TS非常重要的一个特点

  • 通过类型声明可以指定TS中变量(参数,形参)的类型

  • 指定类型后,当为变量赋值时,TS编译器会自动检查是否符合声明,符合则赋值,否则会报错

  • 简而言之,类型声明给变量设置了类型,使得变量只能存储某种类型的值

  • 语法:❶ let 变量:类型;❷ let 变量:类型 = 值;❸ function fn(参数1:类型;参数2:类型):类型{  …  }

  • 自动类型判断:

    • TS拥有自动的类型判断机制

    • 当对变量的声明和赋值是同时进行的,TS编译器会自动判断变量的类型

    • 所以如果你的变量的声明和赋值是同时进行的,可以省略掉类型声明

3、TS中类型

  • #### 类型

3.1、Boolean 类型

如果没有指定boolean类型,但是赋值是布尔类型的(即声明和赋值是同时进行的),ts可以自动对变量进行变量检测

var d = false;
// d = 123 // 会报错
d = true;

  • 具体栗子

let isShow=true; //推断类型,isShow根据值被编译器推断为boolean类型

//isShow=1; //错误不能将类型“number”分配给类型“boolean”。ts(2322)

//isShow=new Boolean(true); //错误,返回的是Object

isShow=Boolean(1); //正确的,返回的是boolean类型的false

isShow=Boolean(0); //false

isShow=Boolean(undefined); //false

isShow=Boolean(null); //false

isShow=Boolean(""); //false

isShow=Boolean({}); //true

console.log(isShow);

3.2、Number 类型

  • 具体栗子

// 在ts的写法
// 意思是:声明了一个变量a,同时指定它的类型为number
var a;
// a 的类型数组为了number,在以后的使用过程中a的值只能是数字
a = 10;
a = 33;
// 此行会报错了,因为上面变量a指定的是数字类型,所以这里不能是其他类型的
// a = "hello";
// 虽然这行会报错,但是进行编译还是会成功的

3.2、String 类型

// let 会编译成 var , 默认编译成js3版本
var b;
b = 'hello';

  • 具体栗子

其中 ` 用来定义 ES6 中的模板字符串${expr} 用来在模板字符串中嵌入表达式

//字符串 string String

let studentname:string="tom";
let studentage:number=18;

let result=`我叫${studentname},明年${++studentage}岁`;
//result=100; //错误,因为模板字符串被推断为string数据类型
console.log(result); //我叫tom,明年19岁

let a=new String("hello world");
console.log(typeof a); //object

//let b:string=new String("hello world"); //不能将类型“String”分配给类型“string”。 object

let c:string=String(true);
console.log(c); //true

3.3、Symbol 类型

const sym = Symbol();
let obj = {
[sym]: "semlinker",
};

console.log(obj[sym]); // semlinker

3.4、js 函数类型

// js中的函数是不考虑参数类型和个数的
function sum(a,b){
return a + b;
}

// console.log(sum(123, 456)); // 579
console.log(sum(123, '456')); // '123456'

3.5、ts 函数类型

// 但是可以给参数指定类型声明
function sum2(a:number,b:number){
return a + b;
}

// sum2(123,"456"); // 会报错,因为ts是一门比较严格的语言

3.6、给函数指定类型声明

// 给函数指定类型声明,就表示返回值的类型
function sum3(a:number,b:number):number{
return a + b;
}
let result = sum3(123,456);
// let result2 = sum3("123",456);//报错

3.7、字面量

// 直接使用字面量进行类型声明
// 但是已经赋值过的不能再进行修改,否则会报错,像常量一样,限制了它的值
let a: 18;
a = 18;
// a = 10; // 报错

3.8、联合类型

// |:表示“ 或 ”的意思,这两个值,随便一个都可以
// 可以使用 | 来连接多个类型(也叫联合类
// b = "false";
// // b = "hello"; // 报错型)
let b: "male" | "false";
b = "male";

// 栗子:
let c: boolean | string;
c = "hello";
c = false;

3.9、any 类型

// any 表示任意类型,一个变量设置类型为any后相当于对该变量关闭了TS的类型检测(所以这个不推荐使用)
// 在使用TS时,不建议使用any类型
let d: any; // 显式类型(直接声明类型)

// let d; 声明变量时,如果不指定类型,则TS解析器会自动判断变量的类型为any(隐式类型)
d = 10;
d = "hello";
d = true;

3.10、unknown类型

// unknown:表示未知类型的值,当自己不知道用什么类型的时候,就使用这个类型
let e: unknown;
e = 10;
e = "hello";
e = true;

// 把变量d的值,赋给s,d的类型是any,它可以赋值给任意变量,不会报错
let s: string;
s = d;
// 但是any类型会关闭TS的类型检测,赋值给s变量的话就会把s变量的类型检测也关闭掉,但是unknown就不会,这就是使用unknown的好处

// 用unknown类型的值就不能赋值给string类型,会报错,这就是any与unknown之间的区别
// s = e;

// unknown实际上就是一个类型安全的any,unknown类型的变量不能直接赋值给其他变量
// 除非:
// 方法一:先给他进行一个类型检测判断
if (typeof e === "string"){
s = e;
}
//方法二:进行类型断言(就是一个判断语言)可以用来告诉解析器变量的实际类型
/**
* 类型断言语法:
* 变量 as 类型
* <类型>变量
*/
s = e as string; // 写法一
s = e; // 写法二

3.11、void类型

// 不写返回值的,函数默认为void类型,写了返回值的按返回值的类型为函数的类型
function fn(){
}

// 按照返回值情况,函数类型为:function fn2(num: any): true | 123
function fn2(num){
if (num>0){
return true;
}else {
return 123;
}
}

// void 用来表示空值,以函数为例,就表示没有返回值的函数
function fn3(): void{
// return xxx; // 只要有返回值就会报错
// return null 或 undefined; // 就不会报错
}

3.12、never类型

// never 表示永远不会返回结果,没有值
// 与void不同的地方是:连null和undefined都不返回
// 利用never来完成报错功能,因为它永远不会返回结果!
function fn4(): never{
throw new Error("报错啦!");
}

3.13、object类型

// object表示一个js对象
let a: object;
// 以下的两种也是一个对象
a = {};
a = function (){};

// {}:用来指定对象中可以包含哪些属性
// let b: {};
// 语法: {属性名1:属性值1,属性名2:属性值3, …}

// 这个与变量a的区别是:这里可以添加一些属性和方法
// 在属性名后面加上?:表示这个属性是可选的,有也可以,没有也不会报错
let b: {name: string,age?: number};
// b = {}; // 这里会报错,因为找不到上面的那个name属性
b = {name: "大美女"};
b = {name: "大美女",age:18};

// [自定义变量名称:属性名类型为字符串]: 任意类型 : 这里表示任意类型的属性
// 要求这个属性必须有一个name属性,其他的任意都可以,有没有都可以
let c:{name: string,[propName: string]: any};
c = {name: "陶陶",age: 18,sex: "女"};

/***
* 定义函数结构:
* 利用箭头函数,设置函数结构的类型声明
* 语法:(形参1:类型,形参2:类型,…)=> 返回值
* 这样写函数d的时候,定义形参时就会自动给形参生成类型声明
*/
let d: (a: number,b: number)=>number;
d = function (n1,n2): number{
return n1 + n2;
}

3.14、array类型

/***
* 数组的类型声明方法:
* 方法一:类型[]
* 方法二:Array<类型>
*/

// string[]:表示字符串数组,字符串数组里只能存放字符串类型的数据,不能存放其他类型的数据
let e: string[];
e = ["a","b","c"];

// number[]:表示数值数组
let f: number[];

// Array:这个也是表示数值类型的数组
let g: Array;
g = [1,2,3];

3.15、tuple(元祖)类型

/***
* 元祖:就是固定长度的数组,当自己数组的数据是固定的时候就可以用
* 语法:[类型1,类型2,类型3,…]
*/
let h: [string,number];
h = ["hello",123];

3.16、enum(枚举)类型

/***
* enum:枚举,一般 结果是在多个值之间进行选择的时候就可以用枚举了
* 一般性别都是男或女的
*/
// 表示在这里定义了一个枚举,里面写我们需要用到的值
enum Gender{
Male,// 表示男
Female// 表示女
}
let i: {name: string,gender: Gender};// 这里就可以直接用Gender作为类型存进去
i = {
name: "大美女",
gender: Gender.Female
}

console.log(i.gender === Gender.Female);//true

3.17、 &(且)

// &:表示同时、且、与的意思
// 变量j必须同时满足name是字符串类型,age是数值类型两个条件
// 连接两个对象
let j: { name: string } & { age: number };
j = {name: "大美女",age: 18};

// 类型的别名:简化类名的使用
type myType = string; // 创建了一个类型别名
let k: 1 | 2 | 3 | 4 | 5;
let l: 1 | 2 | 3 | 4 | 5;
let m: myType; // 但是这样没有意义

// 但是我们可以给一些长的数据加别名
type myType2 = 1 | 2 | 3 | 4 | 5;
let k2: myType2;
let l2: myType2;

4、编译选项(让 ts 的编译变得更优雅)

目的:为了不用每次改变编译代码后,要再次执行 tsc xx.ts 的命令,去编译为js代码

4.1、自动编译文件

编译文件时,使用 -w 指令后,TS编译器会自动监视文件的变化,并在文件发生变化时对文件进行重新编译。

命令:

tsc xx.ts -w

4.2、自动编译整个项目

  • 如果直接使用 tsc 指令,则可以自动将当前项目下的所有ts文件编译为js文件。

  • 但是能直接使用tsc命令的前提时,要先在项目根目录下创建一个ts的配置文件 tsconfig.json,选择文件根目录,右击选择 new => tsconfig.json

  • tsconfig.json是一个JSON文件,添加配置文件后,只需只需 tsc 命令即可完成对整个项目的编译

  • 配置选项:

    • include用来指定哪些ts文件需要被编译;默认值:[" **/* "]

      路径:\*\* 表示任意目录  
           \* 表示任意文件
    • exclude:不需要被编译的文件目录
      默认值:["node_modules","bower_components","jspm_packages"]
      就算是不写exclude,以上的文件都是默认不需要编译的,所以exclude是可选的

    • exclude:定义被继承的配置文件

    • files:指定被编译文件的列表,只有需要编译的文件少时才会用到  

    • compilerOptions:编译器的选项

    • target:用来指定 ts 被编译为 ES 的版本

    • 可选值: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'es2021', 'es2022', 'esnext'(最新版)

    • module:指定要使用的模块化的规范

      • 可选值: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015', 'es2020', 'es2022', 'esnext', 'node16', 'nodenext'
    • lib:用来指定项目中要使用的库,out:用来指定编译后文件所在的目录,例如:“outDir: './dist'”

      • 可选值:ES5、ES6/ES2015、ES7/ES2016、 ES2017、 ES2018、 ES2019、 ES2020、 ESNext、 DOM、WebWorker. ScriptHost ..
    • outDir: 编译后文件的所在目录,默认情况下,编译后的js文件会和ts文件位于相同的目录,设置outDir后可以改变编译后文件的位置

    • outFile:将所有的文件编译为一个js文件,默认会将所有的编写在全局作用域中的代码合并为一个js文件,如果module制定了None、System或AMD则会将模块一起合并到文件之中

    • rootDir:指定代码的根目录,默认情况下编译后文件的目录结构会以最长的公共目录为根目录,通过rootDir可以手动指定根目录

    • allowJs:是否对js文件编译

    • checkJs:是否对js文件进行检查

    • removeComments:是否删除注释

    • noEmit:不对代码进行编译

    • sourceMap:是否生成sourceMap,默认值:false

    • 严格检查

      • strict:启用所有的严格检查,默认值为true,设置后相当于开启了所有的严格检查
      • alwaysStrict:总是以严格模式对代码进行编译

在 TypeScript 中,我们使用接口(Interfaces)来定义对象的类型。