TypeScript完整学习 --【比降价金还值!】
TypeScript简介:
TypeScript
由微软开发,是基于JavaScript
的一个扩展语言。TypeScript
包含了JavaScript
的所有内容,即:TypeScript
是JavaScript
的超集。TypeScript
增加了:静态类检查、接口、泛型等很多现代开发特性,因此更适合 大型项目 的开发。TypeScript
需要编译为JavaScript
,然后交给浏览器活其他JavaScript
运行环境执行。
JS中一些困扰:
- 不清不楚的数据类型
let sum = 123
sum() // sum is not a function
- 有漏洞的逻辑
const str = Date.now() % 2 ? "奇数" : "偶数";
if (str !== "奇数") {
alert("hello");
} else if (str === "偶数") {
alert("wrold");
}
- 访问不存在的属性
const obj = {
width: 10, height: 20 };
const area = obj.width * obj.heigth; //不存在的属性
- 低级的拼写错误
const message = "hello,world!";
message.toUperCase(); //错误的拼写不报错
等等…【具体可见TS官网】
静态类型检查:
在代码运行前进行检查,发现代码的错误或不合理指出,减少运行时异常出现的几率 ===>静态类型检查。 TypeScript
的核心就是静态类型检查。【即:把运行时的错误前置】
所以JavaScript
一些困扰在TypeScript
里不存在
编译TypeScript:
命令行编译【基本不用】:
第一步:创建一个 index.ts
文件
const person = {
name: "张三",
age: 18
}
console.log(`我叫${
person.name},我今年${
person.age}岁了`);
第二步:在终端全局安装 TypeScript
npm i typescript -g
第三步:使用命令编译 .ts
文件
tsc index.ts
每次ts文件修改的时候,都需要进行命令编译,数据才会发生改变。
自动化编译:
都是在终端执行!
第一步:创建TypeScript
编译控制文件
【这个命令工程会生成一个tsconfig.json
的配置文件,其中包含着很多编译配置。我们发现配置文件中默认"target": "es2016",
,即默认版本是ES7
,我们可以手动调整为其他版本】
tsc --init
第二步:监视目录中所有的.ts
文件变化
tsc --watch
第三步:小优化,当编译出错时不生成 .js
文件
tsc --noEmitOnError --watch
【当前也可以修改 tsconfig.json
中的noEmitOnError
配置】
"noEmitOnError": true,
推荐第二步+"noEmitOnError": true,
,不推荐直接tsc --noEmitOnError --watch
。所有的配置都应该调配置文件。
其实如果是使用vue/react的话是不需要我们去专门编译TS的,因为基于webpack/vite。官方提供的脚手架,可以直接写ts,自动给你编译。
-------------一条优雅的分割线【正式TypeScript学习】-----------
类型声明:
使用 :
来对变量或函数形参,进行类型声明
let a: string // 变量a只能存储字符串
let b: number // 变量b只能存储数据
let c: boolean //变量c只能存储布尔值
a = 'hello'
b = 99
c = false
console.log(a, b, c);
// 限制函数接收参数x,y必须是number类型 + 限制返回类型也为number,且调用count的参数必须是两个(限制严格要求)
function count(x: number, y: number): number {
return x + y
}
let result = count(1, 2)
console.log(result);
在 :
后也可以写字面量类型,不过实际开发中用的不多
let a: 'hello'
let b: string
b = 'axx'
b = 'hello wrold'
// a='xxxx'// 错误的,如果是字面量声明,那么就只能是声明的那个值
a = 'hello'// 正确的
类型推断:
// typescript会推断变量d的类型是数字
let d = -11
// d='hello' //警告:不能将类型“string”分配给类型“number”
类型总览:
JavaScript中的数据类型:
string
number
boolean
null
undefined
bigint
symbol
object
备注:object
包含Array
、Function
、Date
、Error
等…
TypeScript中的数据类型:
- 上述所有JavaScript类型 ⬆
- 六个新类型:
any
unknown
never
void
tuple
enum
- 两个用于自定义类型的方式:
type
interface
注意点:
在
JavaScript
中的这些内置构造函数:Number
、String
、Boolean
,它们用于创建对应的包装对象,在日常开发时很少使用,在TypeScript
中也是同理,所以在TypeScript
中进行类型声明时,通常都是用小写的number
、string
、boolean
let str1: string //TS官网推荐的写法
str1 = 'hello'
//不能将类型“String”分配给类型“string”。
//“string”是基元,但“String”是包装器对象。如可能首选使用“string”。
// str1 = new String('hello')
// 此时的str2可以是字符串的原始对象,也可以是字符串的包装对象
let str2: String
str2 = 'hello'
str2 = new String('hello')
console.log(typeof str1); //string
console.log(typeof str2); //object
原始类型 vs 包装对象?
- 原始类型:如
number
、string
、boolean
,在JavaScript
中时简单数据类型,它们在内存中占用空间少,处理速度快。 - 包装对象:如
Number
对象、String
对象、Boolean
对象,是复杂类型,在内存中占用更多空间,在日常开发时很少由开发人员自己创建包装对象。
自动装箱是什么?【了解】
自动装箱是 JavaScript
在必要时会自动将原始类型包装成对象,以便调用方法或访问属性。
//原始类型字符串
let str = 'hello'
// 当访问str.length时,JavaScript引擎做了以下工作:
let size = (function () {
// 1.自动装箱:创建一个临时的String对象包装原始字符串
let tempStringObject = new String(str);
// 2.访问String对象的length属性
let lengthValue = tempStringObject.length;
// 3.销毁临时对象返回长度值(JavaScript引擎自动处理对象销毁,开发者无感知)
return lengthValue;
})();
console.log(size); // 5
常用类型:
any:
any
是任意类型的,一旦将变量类型限制为any
,那就意味着放弃了对该变量的类型检查。
let a: any // 显示any
a = 99
a = 'hello'
a = false
let b // 隐式any(没有明确表示b的类型,ts自动推断为any)
b = 1199
b = '11hello'
b = true
注意点:any类型的变量,可以赋值给任意类型的变量
let a: any // 显示any
a = 99
a = 'hello'
a = false
let x: string
x = a //打印为false且无警告
unknown:
unknown
是未知类型,可以理解为一个类型安全的any
,适用于不确定数据的具体类型。
let a: unknown
a = 99
a = true
a = 'hello'
let x: string
// x = a //不能将类型“unknown”分配给类型“string”
unknown
会强制开发者在使用之前进行类型检查,从而提供更强的类型安全性。
let a: unknown
a = 99
a = true
a = 'hello'
let x: string
// 第一种:
if (typeof a === 'string') {
x = a
}
// 第二种:(断言)
x = a as string
// 第三种:(断言)
x = <string>a
- 读取
any
类型数据的任何属性都不会报错,而unknown
正好与之相反。
let str1: string
str1 = 'hello'
str1.toUpperCase() //无警告
let str2: any
str2 = 'hello'
str2.toUpperCase() //无警告
let str3: unknown
str3 = 'hello';
// str3.toUpperCase() //警告:“str3”的类型为“未知”。
// 可以做断言或判断来进行书写这段代码
(str3 as string).toUpperCase()
never:
never
是任何值都不是,简而言之就是不能有值,undefined
、null
、' '
、0
都不行!
- 几乎不用
never
去直接限制变量,因为没用意义 never
一般是TypeScript
主动推断出来的
let a: string
a = 'hello'
if (typeof a === 'string') {
console.log(a.toUpperCase);
} else {
console.log(a); // TypeScript 会推断出这里的a是never,因为没有任何一个值符合此处的逻辑
}
never
也可以用来限制函数的返回值【一般是用在:一直在循环永远调用不完的函数或是直接抛出异常的函数】
// 限制demo函数不需要有任何返回值,任何值都不行,像undefined、null都不行
function demo(str: string): never {
throw new Error('程序运行异常!' + str)
}
void:
- void通常用于函数返回值声明。含义是函数返回值为空,调用者也不应依赖其返回值进行任何操作
function logMessage(msg: string):void {
console.log(msg);
// void返回值为空 只认undefined 写下面这句话相当于不用写
// return undefined
}
logMessage('你好啊')
注意:编码者没有编写
return
去指定函数的返回值,所以logMessage
函数是没用显示返回值的,但是它会有一个隐式返回值,就是undefined
;即:虽然函数返回类型为void
,但是可以接收undefined
【undefined
是void
可以接收的一种 “ 空 ”】
- 以下写法均符合规范:
function logMessage1(msg: string): void {
console.log(msg);
}
function logMessage2(msg: string): void {
console.log(msg);
return;
}
function logMessage3(msg: string): void {
console.log(msg)