一.Ts最终是会编译成JS代码的,所以我们需要搭建对应的环境:
我是选择全局安装的(我是windows 系统 打开cmd)
1. TypeScript环境安装命令: npm install typescript -g
2. 查看TypeScript版本: tsc --version
二.使用TypeScript定义一个字符串类型:

二.一 使用TypeScript定义一个函数,函数参数定义为串类型:

三.当你写了一段TS代码以后,该怎么样运行呢?
01. 首先你要使用命令: tsc "更上你的书写文件名称" // 转换为相同名称的JavaScript代码
-- 例如: tsc .\01_Hello_TypeScript.ts
实际截图:

三.一 当如果你在TS 文件中书写的代码有错误时,不去解决错误的话, 执行 tsc "文件名称", 这个命令的话,就会报错了:

三.二 如何在浏览器中去运行TS代码呢?
01. 首先使用 tsc "文件名称"; // 把TS的代码转换为JS代码
02. 然后在index.html页面使用script去引用 js 代码
实际截图:

三.三 当定义一些常量的时候,代码会莫名的出现报错情况

/******以上那种编译模式太麻烦了,没改动一次就编译,那太麻烦了******/
四.解决typeScript中编写代码能时时在终端中运行的的几种方案:
1. node中有一个库叫: ts-node,可以在本地的电脑上安装(学习语法的时候可以按照这个方式来创建)
2. 使用webpack搭建TypeScript运行环境
3. vite脚手架去搭建TypeScript运行环境
四.一 ts-node 如何安装呢?
1. ts-node 安装命令: npm install ts-node -g (全局安装)
2. ts-node 这个安装完成以后,他是需要在自己本身的基础上又要依赖两个包的
-- npm install tslib @types/node -g (全局安装)
实际截图

四.一 ts-node 安装完成后如何使用这个命令在终端中运行TypeScript代码呢?

四.二 使用webpack搭建TypeScript运行环境流程图:






五. 一 在TypeScript中的变量声明:
1. 在TS中定义变量需要指定 标识符 的类型,完整的声明格式如下:
-- 声明了类型后 TS 就会进行类型检测, 声明的类型可以称之为类型注解;
var/let/const 标识符: 数据类型 = 赋值;
var age:number = 18
实际截图

五.二 小写的string 和大写的String,小写的number和大写的Number...他们的区别:
// 小写的string: 代表是TypeScript中的字符串的类型
// 大写的String: 代表是JavaScript的字符串的包装类的类型

五.三 类型的推断:
默认情况下进行赋值时, 会将赋值的值的类型,作为前面标识符的类型,也就是说,当你第一次赋值是什么类型的话, 那么就直接给给变量就变为了什么类型的,比如说第一次赋值是个数字,那么他就是个number类型的了
image.png
image.png
五.四 TSlint安装:
为啥要安装TSLint呢? 因为可以让咱们更加规范的书写ts代码
安装命令: tslint --init
六.JavaScript类型-number类型在TypeScript中如何使用
数字类型是我们开发中经常使用的类型,TS和JS一样, 不区分整数类型和浮点数类型,统一为number类型
let num:number = 123;
num = 222; // 赋值数字类型
num = "1233"; // 这种是字符串,就会直接报错了
实际截图

七. boolean类型只有两个取值:true和false
// 1. 定义布尔值:
let flag:boolean = true;
flag = false
// 2. 表达式
flag = 20 > 30
八. string类型的使用
// 1. 字符串的定义
let message1 = 'Hello World!';
let message2 = 'Hello World!';
// 2. 模板字符串使用
const name = '胡振楚';
let message3 = `${name},今年已经18岁啦~`;
console.log(message3);
export {}
实际截图

九.一 Array类型的基本语法一: 不推荐--因为在React中写jsx会有冲突的
/**
* 1. 定义数组类型
* -- 确定一个事实,names是一个数组类型,但是数组中存放的是什么类型的元素呢?
*
* 2. 一个数组中在TypeScript开发中,最好存放的数据类型是固定的(string)
* **/
// 在数组类型存放不同类型是不好的习惯
// const names = []
// names.push("abc");
// names.push(123);
// 3. 数组的基本语法: let/const/var 变量名: Array类型<数组中具体是什么类型的比如: string.....> = []
const names: Array<string> = []; // 一旦这种定义的话,数组中存放的必须全部只能是字符串类型的
names.push(123); // 因为上面定义的只能是字符串所以这种会直接报错
names.push("123");
实际截图

九.二 Array类型的基本语法二: 推荐
const names1:string[] = []
names1.push('huzhenchu')
console.log(names1);

十.一 Object类型的基本用法:
// 1. 对象的基本定义,但是如果你不写注解的话,它会自己推导出来的
const info = {
name: "huzhenchu",
age: 18
}
实际截图

十一.undefined和null类型
// 1. null类型只能赋值为null
const n1: null = null;
// n1 = "abc";
// console.log(n1);
// 2. undefined基本定义:
let n2: undefined = undefined

十二. Symbol类型
const title1 = Symbol("title")
const title2 = Symbol("title")
const info = {
[title1]:"程序员",
[title2]: "厨师"
}
export {}
十三.TypeScript类型 - any类型--- 一下都是Javascript中没有的类型
在某些情况下,确实无法确定一个变量的类型,并且可能它会发生一些变化,这个时候可以使用any类型
1. any类型有点像一种讨巧的TypeScript手段:
-- 可以对any类型的变量进行任何的操作,包括获取不存在的属性、方法;
-- 给一个any类型的变量赋值任何的值,比如数字、字符串的值;
let message:string = "我是胡振楚!";
// 如果上面那种声明了的话,后面再想给message赋值的话,只能赋值字符串了,如果是其他类型的就会立刻报错
2. 但是有的时候确实想修改这个message的类型 想把message的类型变为其他类型那该咋办呢?
-- 可以赋值为any类型,any: 任何的,所有的
let message2: any = "我是楚楚胡";
message2 = 123;
message2 = false
实际截图

十四. TypeScript类型 - unknown类型
unknown是TypeScript中比较特殊的一种类型,它用于描述类型不确定的变量。一般是推荐使用这个类型的,any是不推荐使用的
function foo() {
return "abc"
}
function bar() {
return 123
}
let flag = true;
let result; // 具体的不确定这个result到底是字符串类型的还是数字类型的时候,就用unknown类型
if(flag) {
result = foo()
}else {
result = bar()
}
console.log(result);
实际截图

总结: unknown类型 和 any类型有什么区别?
- unknown 类型只能赋值给any 和 unknown类型
any类型可以赋值给任意类型
image.png
image.png
十五.TypeScript类型 - void类型
void通常用来指定一个函数是没有返回值的,那么它的返回值就是void类型:
可以将null和undefined赋值给void类型,也就是函数可以返回null或者undefined
image.png
这个函数我们没有写任何类型,那么它默认返回值的类型就是void的,我们也可以显示的来指定返回值是void:
function sum (num1:number,num2:number):void {
console.log(num1+num2);
}
sum(20,30);
十六. TypeScript类型 - never类型
never 表示永远不会发生值的类型,比如一个函数:
-- 如果一个函数中是一个死循环或者抛出一个异常,那么这个函数会返回东西吗?
-- 不会,那么写void类型或者其他类型作为返回值类型都不合适,我们就可以使用never类型
function foo(): never {
// 死循环
while (true) { }
}
应用场景:
function handleMessage(message: string | number | boolean) {
switch (typeof message) {
case 'string':
console.log("string方式处理message");
break;
case 'number':
console.log("number方式处理message");
break;
case 'boolean':
console.log("boolean方式处理message");
break;
default:
const check: never = message
}
}
handleMessage("abc")
handleMessage(123)
handleMessage(true)
十七. TypeScript类型 - tuple类型
tuple是元组类型,很多语言中也有这种数据类型,比如Python、Swift等。如果确实想把多个不同的类型的数据放到数组中该怎么办呢?
// 1.元组的使用:
const info:[string,number,number] = ["hzc", 18, 1.88]
const name = info[0];
console.log(name);
console.log(name.length);
console.log(age.length);


应用场景:
1. 那么tuple和数组有什么区别呢?
-- 首先,数组中通常建议存放相同类型的元素,不同类型的元素是不推荐放在数组中。(可以放在对象或者元组
中)
-- 其次,元组中每个元素都有自己特性的类型,根据索引值获取到的值可以确定对应的类型;
function useState(state: any) {
let currentState = state
const changeState = (newState: any) => {
currentState = newState
}
const tuple: [any, (newState: any) => void] = [currentState, changeState]
return tuple
}
const [counter, setCounter] = useState(10);
setCounter(1000);
const [title, setTitle] = useState("abc")
应用场景(优化)
// 1. 那么tuple和数组有什么区别呢?
// -- 首先,数组中通常建议存放相同类型的元素,不同类型的元素是不推荐放在数组中。(可以放在对象或者元组
// 中)
// -- 其次,元组中每个元素都有自己特性的类型,根据索引值获取到的值可以确定对应的类型;
function useState<T>(state: T) {
let currentState = state
const changeState = (newState: T) => {
return currentState = newState
}
const tuple: [T, (newState: T) => void] = [currentState, changeState]
return tuple
}
const [counter, setCounter] = useState(10);
console.log(counter);
console.log(setCounter(1000));
const [title, setTitle] = useState("abc")
console.log(title);
console.log(setTitle("啊哈哈哈哈"));
// 函数类型的写法:
// const foo: () => void = () => { }
// type MyFunction = () => void
// const foo1: MyFunction = () => { }
export { }
十七到十八之间插入一个(函数的参数和返回值类型加注解)
// 1.给函数的参数加上类型注解: num1:number,num2:number=
function sum(num1: number, num2: number) {
return num1 + num2
}
// 2. 函数的返回值加注解
/**
* 2.1 当函数没有返回值的时候是:void
* 2.2 我现在写的这个是一个有返回值的 所以最后他的返回值是:number
* 2.3 在开发中,通常情况下可以不写返回值的
* **/
function sum1(num1: number, num2: number):number {
return num1 + num2
}
十七到十八之间插入一个(匿名函数的参数类型)
// 通常情况下,在定义一个函数时, 都会给参数加上类型注解
function foo(message: string) { }
const names = ['abc', 'cba', 'nba'];
// 他是怎么知道这个item是一个字符串类型呢? -- item 根绝上下文的环境推导出来的,这种情况下是可以不写参数注解
names.forEach(item => { // 这种情况下是可以不写参数注解
console.log(item.length);
})
export { }
十七到十八之间插入一个 (函数参数-对象类型)
// 单个类型的数据
function print(message: number) { }
// 对象类型的数据 Point: x/y 一句话:这里传递一个对象到这个函数中的场景
// 逗号 / 分号 都可以
// point: { x: number, y: number }: 这个的意思就是: 传递一个point但是这个地方必须是一个对象,对象中必须包含x,x必须是一个number类型,y必须也是一个对象类型
function printPoint(point: { x: number, y: number }) {
console.log(point.x);
console.log(point.y);
}
printPoint({ x: 123, y: 456 }); // 这里传递一个对象,对象中必须包含 x,y 类型是number类型
实际截图

十七到十八之间插入一个 (函数参数-可选类型)
// 单个类型的数据
function print(message: number) { }
/**
* 1. 以上是必传类型的
* 对象类型的数据 Point: x/y/z 一句话:这里传递一个对象到这个函数中的场景
* 逗号 / 分号 都可以
* point: { x: number, y: number }: 这个的意思就是: 传递一个point但是这个地方必须是一个对象,对象中必须包含x,x必须是一个number类型,y必须也是一个对象类型,
*
* **/
function printPoint(point: { x: number, y: number }) {
console.log(point.x);
console.log(point.y);
}
printPoint({ x: 123, y: 456 }); // 这里传递一个对象,对象中必须包含 x,y 类型是number类型
printPoint({ x: 123, y: 456 });
/**
* 2. 以下是可传类型
* 需求: 当有个z 参数 这个是可传可不传的,在TS中该如何书写呢?
* point: { x: number, y: number,z?:number } 传递一个point但是这个地方必须是一个对象,对象中必须包含x,x必须是一个number类型,y必须也是一个对象类型,Z是可选类型
*
* 可选类型的基本语法: 参数?: 数据类型(z?:number)
*
* **/
function printPoint1(point: { x: number, y: number, z?: number }) {
console.log(point.x);
console.log(point.y);
console.log(point.z,"point.z"); // 当他有的时候就显示传入的值,没有值就是undefined
}
printPoint1({ x: 123, y: 456 });
printPoint1({ x: 123, y: 456,z:1000 });
export { }
实际截图

十七到十八之间插入一个 (函数参数-联合类型)
TypeScript的类型系统允许我们使用多种运算符,从现有类型中构建新类型。
我们来使用第一种组合类型的方法:联合类型(Union Type)
-- 联合类型是由两个或者多个其他类型组成的类型;
-- 表示可以是这些类型中的任何一个值;
-- 联合类型中的每一个类型被称之为联合成员(union's members);
注意: 使用联合类型的时候一定要注意: 当如果你传入进来的是参数是一个number类型的话,你去调用字符串的方法那么就会报错,这个一定要注意
/**
* 联合类型
* 当printID中的这个参数有可能别人会 传递的类型有可能是 一个字符串 或者 是一个 数字类型的,此时就可以使用联合类型
*
* 他的作用就是: 通用性很强,可以是number类型也可以是string类型
*
* **/
function printID(id: number | string) {
console.log(id);
}
printID(10)
printID("10")
实际截图

十七到十八之间插入一个 (可选类型和联合类型的关系)
/**
* 让参数本身是一个可选的
*
* 一个参数 一个可选类型的时候,它其实类似是这个参数是: 类型|undefined的联合类型(当是可选的时候,如果你不传,最后打印就是undefined)
*
* **/
function foo(message?: string) {
console.log(message); // undefined
}
foo()
实际截图

十七到十八之间插入一个(类型别名)
我们通过在类型注解中编写 对象类型 和 联合类型,但是当我们想要多次在其他地方使用时,就要编写多 次
// type用于定义类型别名
type UnionType = string | number | boolean;
function printId(id: UnionType) {
console.log(id);
}
printId(10)
实际截图

十八.类型断言as
有时候TypeScript无法获取具体的类型信息,这个我们需要使用类型断言,p比如我们通过 document.getElementById,TypeScript只知道该函数会返回 HTMLElement ,但并不知道它
具体的类型:
// 1. 类型断言:
const el = document.getElementById('hzc') as HTMLImageElement
el.src = "图片地址"
// 2. 类型断言:
class Person {}
class Student extends Person {
studying() {
}
}
function sayHello(p:Person) {
(p as Student).studying()
}
const stu = new Student()
sayHello(stu)
实际截图:

十九.非空类型断言
当我们编写下面的代码时,在执行ts的编译阶段会报错:这是因为传入的message有可能是为undefined的,这个时候是不能执行方法的;
// console.log(message!.length); // 非空断言 !
// console.log(message?.length); // 非空断言 ?
function printMessage(message: string){
console.log(message.toUpperCase) // 这个是会报错的
}
// 非空断言使用的是 ! ,表示可以确定某个标识符是有值的,跳过ts在编译阶段对它的检测;
function printMessage(message: string){
console.log(message!.toUpperCase)
// console.log(message!.length); // 非空断言 !
console.log(message?.length); // 非空断言 ?
}
二十.可选链的使用
可选链事实上并不是TypeScript独有的特性,它是ES11(ES2020)中增加的特性:
可选链使用可选链操作符 ?.;
它的作用是当对象的属性不存在时,会短路,直接返回undefined,如果存在,那么才会继续执行;
这个意思说白了就是: 当你一个对象中要是没有那个属性的时候做出判断,不往下面执行了
image.png
type Person = {
name: string
friend?:{
name:string
age?: number
}
}
const info:Person = {
name:'huzhenchu',
friend:{
name:'chuchuhu',
age: 18
}
}
// 这个意思说白了就是: 当你一个对象中要是没有那个属性的时候做出判断,不往下面执行了
// 就是有值的时候就取,没有值的时候就不取,可以做一下这种判断:
// console.log(info.name);
// console.log(info.friend.name);
if (info.friend) {
console.log("if==>name",info.friend.name);
}
if (info.friend) {
console.log("if==>age",info.friend.age);
}
// 上面用这种if判断是为安全没有问题得,但是要是对象里面的东西多了,这种判断是很繁琐的
// 可以使用: 可选链的使用 ?. 具体语法:
console.log("log==>name",info?.friend?.name);
console.log("log==>age",info?.friend?.age);
export {}

二十一. !!的作用
有时候我们还会看到 !! 这些都是做什么的呢?
1. !!操作符:
-- 将一个其他类型转换成boolean类型;
-- 类似于Boolean(变量)的方式;
// !!的作用
const message = "Hello World";
// 需求: 将message的转换为布尔值,赋值给flag
const flag = Boolean(message); // 把变量放到我们的Boolean函数中去转换为布尔值
console.log(flag); // true
// !message: 一个叹号表示把这个变量取反, !!message: 两个叹号:第一个表示取反,第二个把取反以后的值再来取反
const flag1 = !!message
console.log(flag1); // message: 这个本来是一个字符串,这个字符串是有值的所以为:true,加第一个的时候就变为false了,加第二个的的时候,就变为true了
二十二: ?? 的作用
有时候我们还会看到 ?? 这些都是做什么的呢?
1. ??操作符:
-- 它是ES11增加的新特性;
-- 空值合并操作符(??)是一个逻辑操作符,当操作符的左侧是 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数;
// 有时候我们还会看到 ?? 这些都是做什么的呢?
let message: string | null = null;
// 需求: 当把message赋值给content的时候,如果有值的话就赋值给content,没有值的话就赋值一个默认值,而不是直接把message的null赋值给content
const content = message ?? "你好啊,楚楚胡~";
console.log(content);
// 上面这个 ?? 很像三元表达式
const content1 = message ? message : '你好啊,振楚胡~'
console.log(content1);
export {}
实际截图:

二十三. 字面量推理
除了前面我们所用过的类型之外,也可以使用字面量类型
image.png
具体使用:
image.png
// "hello world"也是可以作为类型的,叫做字面量类型
const message = "Hello,world";
// let num: 123 = 123;
// num = 321
// 字面量类型的意义, 就是必须结合联合会类型
// let align: 'left' | 'right' | 'center' | 'left'
// align = 'right'
// align = 'center'
/**
* 如果你赋值为呵呵,那么就直接报错,
* 因为字面量类型和他的值保持一致,字面量类型是left或者right center,你必须只能写这几个值
*
* **/
// align = '哈哈哈哈'
type Alignment = 'left' | 'right' | 'center' | 'left'
let align:Alignment = 'left'
二十四. 字面量推理 三种处理方法:
这是因为我们的对象再进行字面量推理的时候,info其实是一个 {url: string, method: string},所以我们没办法将一个 string 赋值给一个 字面量 类型。
image.png

二十五.类型缩小
什么是类型缩小呢?
-- 可以通过类似于 typeof padding === "number" 的判断语句,来改变TypeScript的执行路径;
-- 在给定的执行路径中,我们可以缩小比声明时更小的类型,这个过程称之为 缩小;
-- 而我们编写的 typeof padding === "number 可以称之为 类型保护
常见的类型保护有如下几种:
-- typeof
-- 平等缩小(比如===、!==)
-- instanceof
-- in
-- .....
二十五.一 typeof

二十五.二 平等缩小

二十五.三 instanceof

二十五.四 in

二十六.一TypeScript函数类型
1. 在JavaScript开发中,函数是重要的组成部分,并且函数可以作为一等公民(可以作为参数,也可以作为返回值进
行传递)
2. 那么在使用函数的过程中,函数是否也可以有自己的类型呢?
-- 我们可以编写函数类型的表达式(Function Type Expressions),来表示函数类型;
3. 以下代码:
// 1. JS 中一个函数作为另外一个函数的调用
// function foo() {}
// function bar(fn) {
// fn()
// }
// bar (foo)
// 2.在TS中函数类型的定义
// function foo() {}
// function bar(fn:()=> void) { // fn变量的名字: 类型注解()=> void 这个代表他是一个函数类型
// fn()
// }
// bar (foo);
// 3. 在TS中函数类型的定义
function foo() { }
type FnType = () => void
function bar(fn: FnType) { // fn变量的名字: 类型注解()=> void 这个代表他是一个函数类型
fn()
}
bar(foo);
// 4. 定义常量时,编写函数的类型
type AddType = (num1: number, num2: number) => number
const add: AddType = (num1: number, num2: number) => {
return num1 + num2
}
add(20, 30)
二十六.二 TypeScript函数类型解析

二十六.三 参数的可选类型
// 1. 在foo调用的时候只传一个值会报错的,因为你在定义的时候是两个参数,所以说必须要传两个参数
// function foo(x:number, y:number) {
// }
// foo(20)
// 2. 有的时候确实指向传一个参数的时候,我们可以把他写成一个可选参数
// 语法: 变量名?:number
// 可选类型是必须写在必选类型的后面的
function foo(x: number, y?: number) { // 这样的话可以只传一个参数
}
foo(20)
// 3. 注意:可选类型是必须写在必选类型的后面的
function sum(x?: number, y: number) { // 报错
}
sum(20, 30)

注意: 可选类型是必须写在必选类型的后面的

二十六.四 默认参数
// 1. 默认值
function foo(x: number, y: number = 100) {
console.log(x, y);
}
foo(10)
// 2. 如果第一个是有默认值,第二个没有默认值就需要这样赋值了
function bar(x: number = 100, y: number ) {
console.log(x, y);
}
// 第一个参数赋值undefined
bar(undefined,10)
// 3. 注意要是真的有默认值的话,建议还是写到靠后面一点,这样的话压根第二个参数是可以不不传的


二十六.五 剩余参数

二十七.一 可推导的this类型

二十七.二 不确定的this类型

二十七.三 指定this的类型

二十八.一 函数的重载
希望可以对字符串和数字类型进行相加,应该如何编写呢?
image.png
// 1. 这种直接相加是会报错的,你把鼠标放到add上面他会告诉你联合类型的,他依然是不确定的
// function add(a1: number | string, a2: number | string) {
// // a1: Number | String
// // a2: Number | String
// return a1 + a2
// }
// 2. 使用if 判断的方式来解决这个问题,但是要是add中要是第一个参数是 数字 第二个参数是 字符串呢? 这种就很麻烦了
function add(a1: number | string, a2: number | string) {
if (typeof a1 === 'number' && typeof a2 === 'number') {
return a1 + a2
} else if (typeof a1 === 'string' && typeof a2 === 'string') {
return a1 + a2
}
// return a1 + a2;
}
add(20,10)
/**
* 总结: 通过联合类型有两个缺点:
* -- 1. 进行很多逻辑判断(类型缩小)
* -- 2. 返回值的类型依然是不能确定的
*
* **/
// 函数的重载: 函数的名称相同, 但是参数不同的几个函数, 就是函数的重载
// function add(num1: number, num2: number) { }
// function add(num1: number, num2: number, num3: number) { }
// 以上就是函数重载了
// add(num1: number, num2: number): number: 这个的意思是声明的函数中的参数类型是:数字类型的,返回值是: 数字
function add(num1: number, num2: number): number; // 没函数体的写法,也就是没有具体函数的实现的
// add(num1: string, num2: string): string: 这个的意思是声明的函数中的参数类型是:字符串类型的,返回值是: 字符串
function add(num1: string, num2: string): string; // 没函数体的写法,也就是没有具体函数的实现的
// 上面定义了函数重载,那么必须要去使用
function add(num1: any, num2: any): any {
if (typeof num1 === 'string' && typeof num2 === 'string') {
return num1.length + num2.length
}
return num1 + num2
}
let res1 = add(20, 30)
console.log(res1);
let res2 = add('abc', 'cba')
console.log(res2);
// 在函数的重载中, 实现函数是不能直接被调用的
// add({name: "why"}, {age: 18})
export { }
二十八.二 sum函数的重载

二十八.三 联合类型和重载

网友评论