typescript 用法详解
javascript 的痛点
弱类型
变量的数据类型不是固定的,我们可以给一个变量赋值多种不同类型的值。
这样可能代码编写时会更加简单,但当项目变大时,可能会给项目带来一定的隐患,也不便于多人合作
function add (a, b) {
return a + b
}
add(100, 200) // 300
add('a', 100) // 'a100' 这改变了我们函数定义的初衷
强类型
声明变量时,一旦给变量赋值了,那么变量的数据类型就已经确定了,不可在赋值其他类型的值。如果要赋值其他类型的值,必须要先进行强制数据类型转换
动态类型
动态类型的语言在类型检查时,会在代码运行时检查。这就导致了当我们代码存在错误时,需要代码运行后,才能知道。
var obj = {
name: '张三'
}
console.log(obj.age)
这段代码会报错,因为obj并没有age属性。但只有在代码运行时才会报错。这时,我们可能需要一些约束来让我们更早的发现问题
静态类型
静态类型在类型检查时,是在代码编译阶段进行的。能够更早的发现问题
什么是typescript
- typescript是微软推出的javascript的超集,也就是说它支持任何javascript语言,是javascript的一个升级版,给javascript加上了一定的约束性
- typescript 为 javascript提供了类型系统和es6支持(不过现在大多数浏览器也都已经支持es6了)
- typescript 代码的运行最终都要转化为javascript 运行。此时我们就需要用到 typescript 的工具tsc,用于转换ts–>js
tsc的使用
npm i typescript -g // 安装typescript
通过指令 tsc index.ts 可以将ts转换为js运行,他会在特定的地方生成转换出来的js文件

ts配置文件
通过tsconfig.json可以进行一定规则配置。从而让ts文件可以按照一定的规则转换成js文件
创建配置文件
通过 tsc --init 可以在当前目录下生成tsconfig.json文件
tsc --init

tsconfig 常用配置
- target: 将ts转换为哪个版本的javascript 如:es5, es3
- module: 将ts转换成使用哪种模块化标准的javascript 如:commonJs,amd
- outDir: 将ts转换成的js文件放置在哪个路径下 如:./dist 默认是./
- rootDir: 将哪个路径下的ts代码进行转换 如:./src 默认是./
- strict: 转换成的js是否启用严格模式 true or false
使用配置文件
tsc -p ./tsconfig.json
typescript特性
typescript通过在数据定义时,加上类型,来给变量添加一定的约束,变量的类型一旦设定,将不可在给变量设置其他类型的数据,否则编译时就会报错
let num: number = 10 // 给num定义了number类型,后续只能赋值number类型的数据
num = 'abc' // 编译时会报错
typescript各种数据类型的定义
number类型
// number类型 大小写都行 可接收十进制,二进制,八进制和十六进制数
let a: number = 10
let b: number = 0b1010 // 二进制 0b开头
let c: number = 0x1E0F3 // 十六进制 0x开头
let d: number = 0o12 // 八进制 0o开头
let e: number = NaN
let f: number = Infinity
string类型
// string类型
let str1: string = "双引号"
let str2: string = '单引号'
let str3: string = `模板字符串`
boolean类型
let flag1: boolean = true
let flag2: boolean = false
数组类型
两种方式
// Array<数组成员的数据类型>
let arr1: Array<number> = [1,2,3,4,5] // 代表arr1只能赋值数组给它,并且数组的成员都必须是number类型
// 数组成员的数据类型[]
let arr2: number[] = [1,2,3,4,5] // 效果和上面一模一样
元组
元组类型表示一个已知元素数量和类型的数组,数组内各个成员的类型不必相同
// 表示该arr只能接收一个长度是2 且第一个成员类型必须是number, 第二个成员类型必须是string的数组
let arr: [number, string] = [10, 'abc']
arr[0] = '123' // 会报错 只能赋值number类型
arr[1] = null // 会报错 只能赋值string类型
void类型
void类型表示没有任何类型,void类型的数据只能给他赋值undefined ,因此用处不大。
不过,因为他只能赋值undefined, 而一个函数 当没有返回值时会默认返回undefine, 故void可以用来定义没有返回值的函数
let reg: void = undefined
reg = 123 // 会报错
let function aaa(): void {}
undefined类型
undefined类型只能赋一个值 undefined
let un: undefined = undefined
un = 123 // 会报错
null类型
null类型只能赋一个值 null
let nu: null = null
nu = 123 // 会报错
never类型
never 类型一般用来表示一个函数,但只能表示一些永远无法到达终点的函数
// never类型的函数必须存在一个无法到达的终点
function aaa (): never {
throw new Error('抛出一个错误')
}
// never类型的函数必须存在一个无法到达的终点
function bbb (): never {
while(true) {}
}
typeScript中的类
类属性定义
ts中的类和es6 有一点不同的是,ts中的类中的属性,必须在类中定义,并指定类型
正确的做法
class Person {
name: string // 如果在constructor中给他赋值了(也就是初始化了),那么定义时可以不赋值
age: number = 18 // age没在constructor中初始化,故定义时,需要赋值,否则编译时会报错
constructor (name: string, age: number) {
this.name = name
}
}
还有种定义方式是直接在传参时加个访问修饰符 如:
class Person {
// 相当于定义了,并给他赋值了 this.name = name this.age = age
constructor (public name: string, public age: number) {
console.log(this.name) // 此时可以直接调用,因为已经定义了
console.log(this.age) // 此时可以直接调用,因为已经定义了
}
}
等价于下面
class Person {
name: string
age: number
constructor (name: string, age: number) {
this.name = name
this.age = age
}
}
类继承
ts中的类继承和es6中差不多,无非多了个类型限制也会被继承。我就不多说了,直接看代码
class Person {
name: string
age: number
constructor (name: string, age: number) {
this.name = name
this.age = age
}
say (): void {
console.log('你好啊,南昌老表')
}
}
class NanChang extends Person {} // 通过extens实现继承,和es6一样
let chenMing = new NanChang('陈明', 18) // 类型限制也被继承了,因此,第一个参数必须传string, 第二个必须传 number
chenMing.say()
// 输出
你好啊,南昌老表
接口继承
interface inter1 {
name: string,
age: number
}
interface inter2 extends inter1 {
address: string
} // 此时inter2 就是一个具备了3个属性的接口了
// obj继承inter2 就必须有以上3个属性才行
let obj: inter2 = {
name: '陈明',
age: 18,
address: '南昌'
}
接口继承接口也可以同时继承多个 继承多个时,以逗号分隔 如:
interface inter1 {
name: string,
age: number
}
interface inter2 {
address: string
}
interface inter3 extends inter1, inter2{
like: string
} // 此时inter3同时继承了inter1和inter2 就是一个具备了4个属性的接口了
// obj继承inter3 就必须有以上4个属性才行
let obj: inter2 = {
name: '陈明',
age: 18,
address: '南昌',
like: '看美女'
}
接口继承类
顾名思义,接口同样可以继承一个类。当继承某个类时,就会继承这个类中所有的属性和方法。如:
class Person {
name: string
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
say (str: string) {
console.log(str)
}
}
// 此时,peo接口继承了Person类,那么就继承了他的所有属性和方法(包括属性和方法的类型)
interface peo extends Person{
like: string
}
let people: peo = {
name: '陈明',
age: 18,
like: '看美女',
say: function (str) {}
}
接口合并
我们知道,当我们声明同名的变量时,后面的会覆盖前面的。但是对于接口而已,不会覆盖,而会叠加
interface aaa {
name: string
}
interface aaa {
age: number
}
// 以上两句话相当于下面一句话
// interface aaa {
// name: string,
// age: number
//}
let bbb: aaa = {
name: 'chenMing',
age: 18
}
常见内置对象
typescript中有很多全局内置对象,不需要任何引入便可直接用的。
这里列出一些常用的
Date
Error
RegExp
HTMLElement
NodeList
2545

被折叠的 条评论
为什么被折叠?



