TypeScript教程

1. TypeScript 简介

1.1. JavaScript

  javaScript 当年诞生时的定位是浏览器脚本语言,用于在网页中嵌入一些简单的逻辑,而且代码量很少。随着时间的推移,JavaScript 变得越来越流行,如今的 JavaScript 已经可以全栈编程了。现如今的 JavaScript 应用场景比当年丰富的多,代码量也比当年大很多,随便一个 JavaScript 项目的代码量,可以轻松的达到几万行,甚至十几万行。然而 JavaScript 当年“出生简陋”,没考虑到如今的应用场景和代码量,逐渐出现很多困扰。
  JavaScript 中的困扰:
  1. 不清不楚的数据类型

let welcome = 'hello'
welcome() //编译器没有提示,TypeError: welcome is not a function

  2. 有漏洞的逻辑

const str = Date.now() % 2 ? '奇数':'偶数'
if(str !== '奇数'){
   
   
    alert('是偶数') //只会弹出这一个,编译器没有提示
}else if (str === '偶数') {
   
   
    alert('是偶数')
}

  3. 访问不存在的属性

const obj = {
   
   w:10,h:8}
const area = obj.w * obj.hh //编译器没有提示

  4. 低级的拼写错误

const mes = 'hellow,world'
mes.toUperCase() /单词拼写错误,编译器没有提示

1.2. TypeScript

  1. TypeScript 由微软开发,是基于 JavaScript 的一个扩展语言。
  2. TypeScirpt 包含 JavaScript 的所有内容,即:TypeScript 是 JavaScript 的超集。
  3. TypeScript 增加了:静态类型检查、接口、泛型等很多现代开发特性,因此更适合在大型项目的开发。
  4. TypeScript 需要编译为 JavaScript,然后交给浏览器或其他 JavaScript运行环境执行。

静态类型检查:
  在代码运行前进行检查,发现代码的错误或不合理之处,减小运行时异常出现的几率,些种检查叫静态类型检查,即把运行时的错误前置。
同样功能,TypeScript 的代码量要大于 JavaScript,但 TypeScript 代码结构更加清晰,在后期代码维护中 TypeScript 却远胜于 JavaScript

2. 编译TypeScript

浏览器不能直接运行 TypeScript 代码,需要纊译为 JavaScript 再交由浏览器解析器执行

2.1. 命令行编译

要把 .ts 文件编译为 .js 文件,需要配置 TypeScript 的编译环境,步骤如下:

  1. 创建 demo.ts 文件,例如:
const person = {
   
   
	name:"张三",
	age:18
}
console.log(`我是${
     
     person.name},我今年${
     
     person.age}岁了`)
  1. 全局案装 TypeScript
npm i typescript -g
  1. 编译 .ts 文件
tsc demo.ts

2.2. 自动化编译(推荐)

  1. 创建 TypeScript 编译控制文件
tsc --init
# 1.工程中会生成 tsconfig.json配置文件,其中包含着很多编译时的配置。
# 2.观察发现,默认编译的 JS版本是ES7,可手动调整为其他版本
  1. 监视目录中的 .ts 文件变化
tsc --watch
  1. 优化,当编译出错时不生成 .ts 文件
tsc --noEmitOnError --watch
# 推荐在 tsconfig.json配置文件中改

3.类型声明

使用:对变量或函数形参,进行类型声明:

// 1. 具体类型
let a: string //字符串
let b: number //数值
let c: boolean //布尔值

//参数 x,y,函数返回值 必须是数值,
function demo(x: number, y: number): number {
   
   
    return x + y
}

// 2. 字面量类型
let d: 'hello' //d的值只能为字符串“hello”
d = 'hello'

TS 会根据我们的代码,进行类型推导

let a = 100 //TS会推断变量a是数字,但是推荐编写类型声明

4. 类型

4.1. 类型概括

JavaScript 数据类型
string, number, boolean, null, undefined, bigint, symbol, object
备注:object 包含:Array, Function, Date, Error 等

TypeScript 数据类型

  1. 所有 JavaScript 类型
  2. 6个新类型:any, unknown, never, void, tuple, enum
  3. 2个自定义类型方式:type, interface

注意点
在 JavaScript 中的这些内置构造函数:Number, String, Boolean, 它们用于创建对就的包装对象,在日常开发时很少用,在 TypeScript 中也是同理,所以在 TypeScript 中进行类型声明时,通常都是用小写的 number, string, boolean
案例:

let str1: string
str1 = 'hello'
//str1 = new String('hello') //报错
let str2: String
str2 = 'hello'
console.log(str2)
console.log(typeof str1)
str2 = new String('hello')
console.log(typeof str2)
console.log(str2)
  1. 原始数据 VS 包装对象
    • 原始数据:如 number, string, boolean, 在 JavaScript 中是简单数据类型,它们在内存中占用空间少,处理速度快。
    • 包装对象:如 Number对象、String对象、Boolean对象,是复杂类型,在内存中占用空间多,在日常开发时很少由开发人员自已创建包装对象。
  2. 自动装箱: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)

4.2. any

any:任意类型,一旦将变量类型限制为any,即放弃对该变量的类型检查

// 明确表示a类型为 any [显示any]
let a: any
a = 100
a = 'hello'

// 没有表示类型,推断为 any [隐示any]
let b
b = 100
b = 'hello'

// any类型的变量,可以赋值给任意类型的变量
let c: any
c = 9
let d: string
d = c

4.3. unknown

unknown:未知类型

  1. unknown 可以理解为一个类型安全的 any, 适用不确定数据的具体类型
  2. unknown 会强制开发者在使用之前进行类型检查,从而提供更强的类型安全。
  3. 读取 any 类型数据的任何属性都不会报错,而 unknown 正好与之相反。
// 设置a的类型为 unknown
let a: unknown
a = 100
a = 'hello'
let b: string
// b = a 不能将类型"unknown"分配给类型"string"
// 1.类型判断
if(typeof a === 'string'){
   
   
    b = a
}
// 2.断言
b = a as string
b = <string> a

b.toUpperCase()//无警告
let c: any = "hello"
c.toUpperCase()//无警告
let d: unknown
// d.toUpperCase() //警告
(d as string).toUpperCase()

4.4. never

never:任何值都不是,就是不能有值,uedefined,null, “”, 0 都不行

  1. 几乎不用 never 去直接限制变量,因为没有意义。
  2. never 一般是 TypeScript 主动推断出来的
  3. never 也可用于限制函数的返回值
// 指定a的类型为never,即a以后不能存任何数据了
let a:never
// a = 1 //不能赋值

let b:string
b = 'hello'
if(typeof b === 'string'){
   
   
    console.log(b.toUpperCase())
}else {
   
   
    console.log(b) // TypeScript 会推断出此出的a是never,因为没有任何一个值符合此处逻辑
}

// 限制throwError函数需要任何返回值,任何值都不行
// 没有返回值函数,执行完默认返回 unddefined
function throwError(str: string):never{
   
   
    throwError("程序异常退出"+str)
}

4.5. void

void 与 undefined
void 是一个广泛的概念,用来表达“空”,而 undefined 则是这种“空”的具体表现实现之一,因此可以说 undefined 是 void 能接受的“空”状态的一种具体形式。
也就是说:void 包含 undefined ,但 void 表达的语义超越了单纯的 undefined ,它是一种意图上的约定,而不仅仅是特定值的限定。
总结:
void 返回类型的 函数,虽然返回 undefined ,但无所谓,不应该管,不应该用。

//void 通常用于函数返回值声明,含义:函数不返回任何值,调用者也不应依赖其返回值进行任何操作
function logMessage(msg:string):void{
   
   
    console.log(msg)
    // return undefined // ok
    // return; //ok
    /*
    没有 return ,函数没有 显式返回值,
    但会有一个 隐式返回值:undefined;
    即:虽然函数返回类型为void,但也可以接受 undefined.
    */
}
logMessage('hellohello')// 调用时,不应该接收返回值,就算接收了,这个返回值也不能用

function logMessage2(msg:string):undefined{
   
   

}
let res = logMessage2("hello") //调用时,可接收返回值,可使用
if(res){
   
   

}

4.6. object

object 与 Object 实际开发中不用,因为范围太大了

  1. object(小写):所有非原始数据,即对象,函数,数组等
  2. Object(大写):所有可以调用 Object 方法的类型,即除了 undefined、null
let a: object
a = {
   
   name:'张三'}
a = [1,2]
a = function(){
   
   }
a = new String('hello')
class Person{
   
   }
a = new Person()

let b: Object
b = 1

声明对象类型

//限制person对象必须有name属性,age为可选属性
let person: {
   
    name: string, age?: number }

//也可用分号
let person2: {
   
    name: string; age?: number }

//也可用换行
let person3: {
   
   
    name: string
    age?: number
}
person = {
   
    name: "张三", age: 18 }
person = {
   
    name: '张三' }

//索引签名:允许定对象可以具有任意数量的属性,这些属性的键和类型是可变的
let person4: {
   
   
    name: string
    age: number
    [key: string]: any //索引签名,可以不用key,只要占位
}
person4 = {
   
    name: '张三',age: 18, gender: '男' }

声明函数类型

// TypeScript 中的 => 在函数类型声明时表示函数类型,描述其参数类型和返回类型
// JavaScript 中的 => 是一种定义函数的语法,是具体的函数实现
let count: (a:number,b:number) =>number //a,b 相当于占位符,可以是别的值
count = function(w,h){
   
   
    return w*h
}

声明数组类型

let arr1: string[]
let arr2: Array<number> // 泛型
arr1 = ['a','b']
arr2 = [1,2]

4.7. tuple

元组(Tuple)是一种特殊的数组类型,可以存储固定数量的元素,并且每个元素的类型是已知的且可以不同,元组用于精确描述一组值的类型

let arr1:[string,number]
let arr2:[string,number?]
let arr3:[string,...string[]] //...表示任意数量的字符串类型

arr1 = ['hello',100]

4.8. enum

枚举(enum)可以定一组命名常量,增强代码可读性

function walk(str:string){
   
   
    if(str === 'up'){
   
   
        console.log('up')
    }else if(str === 'down'){
   
   
        console.log('down')
    }else {
   
   
        console.log('other')
    }
}
walk('down')//walk函数,参数是字符串,写错没有提示,up、down 是连续相关的一组值,适合使用 枚举(enum)

//改为

// 1.数字枚举
enum Direction {
   
   
    Up,
    Down
}
console.log(Direction) //{0: 'Up', 1: 'Down', Up: 0, Down: 1}
function walk2(data:Direction){
   
   
    if(data === Direction.Up){
   
   
        console.log('Up')
    }else if(data == Direction.Down){
   
   
        console.log('Down'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值