为什么使用TS
因为js没有编译和类型检测的束缚,js天生就是一款非常灵活、容易上手的编程语言,但是这种灵活性也导致我们的程序代码难以维护、尤其是对大型的项目、很多Bug只有在程序运行的时候才能体现出来
TS的出现大程度的弥补了JS的以上缺陷
TS是什么
首先它并不是一个全新的编程语言,而是JS的一个超集,并增加了类型标注,换句话来说,我们所写的JS代码也是合法的TS代码
类型标注就可以检测出我们平时粗心导致的bug
类型标注同时也增强了编辑器自带的代码提示、自动补全的功能、大大提升了开发效率
注意 :TS是不能直接在浏览器或者node环境中运行的
所以就要用到TSC
TSC
在大多数情况下如果我们要执行TS编写的代码,还是需要先将他转译成JS才行,这时候就需要用到TSC(TypeScript编译器)
使用
- 需要安装至全局
- npm i tsc -g
- 然后使用tsc命令跟上源文件完成JS 的转译
tsc xxx.ts - 随后就可以运行编译后的js文件
TypeScript 的常用基础类型以及详细的使用
常用的基础类型分为两大类
1.JS 已有类型
原始类型:number/string/boolean/null/undefined/symbol
// 数值类型
let num: number = 100
// 字符串类型
let str: string = 'abc'
// 布尔类型
let flag: boolean = true
// undefined
let un: undefined = undefined
// null
let timer:null = null
// symbol
let uniKey:symbol = Symbol()
类型推论
在 TS 中,某些没有明确指定类型的情况下,TS 的类型推论机制会自动提供类型。好处:由于类型推论的存在,有些情况下的类型注解可以省略不写
会发生类型推论的两种场景:
- 声明变量并初始化时
- 决定函数返回值时
// 变量 age 的类型被自动推断为:number
let age = 18
// 函数返回值的类型被自动推断为:number
function add(num1: number, num2: number) {
return num1 + num2
}
对象类型: 数组 、 函数 、对象 等对象类型
- 函数类型
// 普通函数
function 函数名(形参1: 类型=默认值, 形参2:类型=默认值,...): 返回值类型 { }
// 箭头函数
const 函数名(形参1: 类型=默认值, 形参2:类型=默认值, ...):返回值类型 => { }
- 对象类型
const 对象名: {
属性名1:类型1,
属性名2:类型2,
方法名1(形参1: 类型1,形参2: 类型2): 返回值类型,
方法名2:(形参1: 类型1,形参2: 类型2) => 返回值类型
} = { 属性名1: 值1,属性名2:值2 }
2.TS 新增类型
- 联合类型
let 变量: 类型1 | 类型2 | 类型3 .... = 初始值
- 自定义类型(类型别名)
type myType1 = number //此时自定义的类型就为number
type myType2 = number | string //此时自定义的类型就为number 和 string
type myType3 = 'abc' //此时自定义的类型就为'abc' ,当变量定义此类型,值就必须为'abc'
- 接口
interface 接口名 {
属性1: 类型1, 属性2: 类型2,
}
interface(接口)和 type(类型别名)的对比:
相同点: 都可以给对象指定类型
不同点:
接口,只能为对象指定类型。它可以继承。
类型别名,不仅可以为对象指定类型,实际上可以为任意类型指定别名
能使用 type 就用 type
接口继承
interface 接口2 extends 接口1 {
属性1: 类型1, // 接口2中特有的类型
...
}
使用 extends(继承)关键字实现了接口的继承
- 元组
let arr : [number,number] = [123,1234] // 此时值必须为数组且元素的个数必须是两个number类型
- 字面量类型
type Gender = 'girl' | 'boy'
let g1: Gender = 'girl' // 正确
let g2: Gender = 'boy' // 正确
let g3: Gender = 'man' // 错误
- 枚举 枚举(enum)的功能类似于字面量类型+联合类型组合的功能,来描述一个值,该值只能是 一组命名常量 中的一个。
定义格式 enum 枚举名 { 可取值1, 可取值2,.. }
- 使用
enum关键字定义枚举 - 一般约定首字符大写
使用格式:
枚举名.可取值
例如
// 定义枚举类型
enum Direction { Up, Down, Left, Right }
// 使用枚举类型
function changeDirection(direction: Direction) {
console.log(direction)
}
// 调用函数时,需要应该传入:枚举 Direction 成员的任意一个
// 类似于 JS 中的对象,直接通过 点(.)语法 访问枚举的成员
changeDirection(Direction.Up)
解释:
- 约定枚举名称以大写字母开头
- 枚举中的多个值之间通过
,(逗号)分隔 - 定义好枚举后,直接使用枚举名称作为类型注解
-
void
在 TS 中,如果一个函数没有返回值,应该使用
void类型
function greet(name: string): void {
console.log('Hello', name)
//
}
//具体来说:有如下三种情况
// 不写return
// 写return ,但是后面不接内容
// 写return undefined
// 如果什么都不写,此时,add 函数的返回值类型为: void
const add = () => {}
// 如果return之后什么都不写,此时,add 函数的返回值类型为: void
const add = () => { return }
const add = (): void => {
// 此处,返回的 undefined 是 JS 中的一个值
return undefined
}
// 这种写法是明确指定函数返回值类型为 void,与上面不指定返回值类型相同
const add = (): void => {}
void和undefined的区别
如果函数没有指定返回值,调用结束之后,值是undefined的,但是不能直接声明返回值是undefined
function add(a:number, b:number): undefined { // 这里会报错
console.log(a,b)
}
- any any: 任意的。当类型设置为 any 时,就取消了类型的限制。
使用any的场景
- 函数就是不挑类型。 例如,
console.log(); 定义一个函数,输入任意类型的数据,返回该数据类型 - 临时使用 any 来“避免”书写很长、很复杂的类型
隐式 any
- 声明变量不提供类型也不提供默认值
- 定义函数时,参数不给类型
原则:不推荐使用 any!这会让 TypeScript 变为 “AnyScript”(失去 TS 类型保护的优势)
- unkown
可选参数,可选属性
在定义类型的时候可以选择有些不定义的值
对象中:在属性名后面加?
函数的参数中 :在参数后加?
元组中:在元素类型后加?
可选和默认值的区别
相同点: 调用函数时,可以少传参数
区别:设置了默认值之后,就是可选的了,不写就会使用默认值; 可选的参数一定有值。
注意:它们不能一起使用。优先使用默认值
持续更新
感谢阅读!!!