简介
TypeScript 是微软公司编写的 javascript 超集,亲爹微软,干爹谷歌。前端框架都上了,小程序业上。包含了 ES5 和 ES6。 TypeScript 对类型的检测为静态检查,不会在生成的 js 文件中存在类型检测的代码。如果发现有错误,编译的时候就会报错,但仍旧生成对应的 js 文件。
四部分
- TypeScript 基础
- TypeScript 面向对象
- TypeScript 与 Vue 结合
- 结合项目实操
TypeScript 基础
- 环境安装运行
TypeScript 是 JS 的超级,ES 部分直接可以在浏览器跑,TS 部分需要 TS 环境
nodejs & npm
1.安装 node,npm install -g typeScript
tsc -v
有版本输出说明成功
tsc
负责将 ts 代码转化为浏览器和 nodejs 识别的 js 代码。
vscode 自动编译
:tsc --init
创建tsconfig.json
文件- 修改
tsconfig.json
设置 js 文件夹"outDir": "./js/"
- vsocde 终端 - 运行任务 - tsc监视当前json,自动监听目录下的所有 .ts文件输出到 outDir
数据类型
JS 是弱类型的,声明变量不需要指定类型。TS 需要指定类型,一旦为变量指定类型,该变量只能在相同类型中改变,否则 TS 报错
原有类型 | 新增类型 |
---|---|
string number boolean array null undefind symbol object | tuple enum anay never void |
- 数组
let arr: type[] = value;
let key:Array<type> = value; // 泛型
let arr: string[] = ['a', 'b'];
let arr: Array<string> = ['a', 'b'];
- 元组
规定了数量和每项类型的数组。TS 中数组元素类型必须保持一致,如果需要不同元素,就需要元组
let key: [type, type, type] = value
let arr:[string, number, boolean] = ['老子', 18, true]
- 枚举
可以省略value,自动从 0 开始
enum key {
key = value
}
enum Gender {
boy,
girl,
unkonw
}
let userSex: Gender = Gender.boy;
- 任意类型
any 代表任意类型,一般用在给变量赋值 DOM 时使用
let box: any = document.querySelector('.box');
- 没有类型
在 TS 中,函数必须指定返回值的类型。void 代表没有类型,一般用在无返回值的函数中
function say(): void {
console.log('say hi');
}
- 不存在的值的类型
never 代表不存在的值的类型,常用作抛出异常或无限循环的函数返回类型
never 类型是 所有 TS 类型的底部类型,所有类型都是 never 类型的父类型,即 enver 类型可以赋值类任意类型的变量
function err(): never {
throw new Error('error')
}
function test(): never {
while(true) {
}
}
let str: string = test(); // string 的 str 却可以赋值为 never 类型
函数
- 函数基本
- 函数必须指定返回类型,如果没有则指定 void 类型
- 实参与形参数量与类型必须一致
- 如果不一致用可选参数
- 函数默认值
带默认值的参数,本身也是可选参数
参: 类型 = 默认值
function fn(name: string = 'zhangsan', age: number = 18): void {
console.log(`${name} say: Hello Word, age ${age}`)
};
fn() => 'zhangsan say: Hello Word, age 18'
fn(undefind, 23) => 'zhangsan say: Hello Word, age 23'
- 剩余参数
- 剩余参数只能有一个
- 只能定义为数组
- 只能在形参数列表最后
function add(num1: number, num2: number, ...rest:number[]): number {
return num1 + num2 +
}
参数类型,返回值,接收变量
实参与形参统一性
小结
基本数据类型
数组
元祖
元祖类型是数组的一种,限定了数组每个 index 上的数据类型
let arr:[number,string] = [1,'a']
枚举
任意
void
never
在 typescript 中没有 object 这个类型,在对对象操作的时候会报错,我们可以指定变量为 any 类型来解决报错
基本类型
JavaScript 没有空值(Void)的概念,在 TypeScript 中,可以用 void 表示没有任何返回值的函数。声明一个 void 类型的变量没有什么用,因为你只能将它赋值为 undefined 和 null
let num: number = 1
let str: string = 'hello world'
let bool: boolean = false
let nu: null = null
let un: undefined = undefined
let vo: void = null || undefined
function alertName(): void { 函数类型指定的是返回值
alert('My name is Tom');
}
特别的,undefined 和 null 也是所有基本类型的子集,可以给 number 类型的变量赋值为 null,但是 void 不行
let num: number = null
let un: undefined = undefined
let num: number = un
但是以下代码会报错
let vo: void = undefined
let num: number = vo
普通类型在赋值过程中改变类型是不被允许的。
let num: number = 1
num = 'hello' 报错 不能将 "string" 分配给类型 number
let str: string = 'hello'
console.log(str.name) 报错 类型 string 上不存在属性 name
any(任意值)类型的,是允许被改变类型的,可以 .出来任意属性和方法
let any; 变量如果在声明的时候,未指定其类型,那么它会被识别为任意值类型
let num: any = 1
num = 'hello'
let num = 1 实测在 vscode 中,不强调类型也会在声明函数的时候默认类型(官方叫类型推论)
num = 'xx' 报错
联合类型
let a: number | string = 1
a = 'hello'
let myFavoriteNumber: string | number;
只能访问此联合类型的所有类型里共有的属性或方法
function fn(name:string | number = 'hello'){
return name.length 报错 类型 number 上不存在属性 length
}
联合类型变量在被赋值的时候,会根据类型推论的规则推断出一个类
let a: number | string = 1
a.length 报错 类型 number 上不存在属性 length
||
let a: number | string = 'hello'
a.length 不报错
接口
https://ts.xcatliu.com/basics/type-of-object-interfaces
在 TypeScript 中,我们使用接口(Interfaces)来定义对象的类型
实测在接口 interface 中,用分号,逗号或者不写都可以
在面向对象语言中,接口(Interfaces)是一个很重要的概念,它是对行为的抽象,而具体如何行动需要由类(classes)去实现(implement)。
TypeScript 中的接口是一个非常灵活的概念,除了可用于对类的一部分行为进行抽象以外,也常用于对「对象的形状(Shape)」进行描述
下面的例子中,我们定义了一个接口 Person,接着定义了一个变量 tom,它的类型是 Person。这样,我们就约束了 tom 的形状必须和接口 Person 一致
确定属性
interface Person {
name: string;
age: number;
}
let tom: Person = {
name: 'Tom',
age: 25
}
注意,变量的形状必须和接口完全一致,多或少属性都报错
interface Person {
name: string;
age: number;
}
let tom: Person = {
name: 'Tom',
age: 25,
gender: 'male'
}
let tom: Person = {
name: 'Tom'
}
可选属性
有时我们希望不要完全匹配一个形状,那么可以用可选属性。但可选属性仍不能多出一个属性
interface Person {
name: string;
age?: number;
}
let tom: Person = {
name: 'Tom'
}
let tom: Person = {
name: 'Tom',
sex: 'man' 报错
}
任意属性
有时候我们希望一个接口允许有任意的属性,可以使用如下方式
interface Person {
name: string
age?: number
[propName: string]: any
}
let tom: Person = {
name: 'Tom',
gender: 'male'
};
只读属性
对象中的一些字段只能在创建的时候被赋值,那么可以用 readonly 定义只读属性
interface Person {
readonly id: number
}
let xiaoming: Persong = {
id: 1
}
xiaoming.id = 2 报错
对属性名限定类型
interface Arr {
[index: number] : number
}
接口简写
let obj: {
name:string,
age:number
} = {
name:'zhangsan',
age:18
}
数组
指定类型
- 类型 + 方括号
let arr: string[] = ['a','b'] 指定一类
let arr; any[] = [1,'a'] 任意类型
???? 如何指定联合类型
- 接口约束
interface Arr {
[index:number]:number|string
}
let arr:Arr = [1,'1']
- 数组泛型
let arr: Array<number> = [1]
类数组
实际上类数组都有自己的接口定义,如 IArguments, NodeList, HTMLCollection
function sum() {
let args: IArguments = arguments;
}
函数
https://ts.xcatliu.com/basics/type-of-function
函数声明(Function Declaration)
function sum(x: number, y: string): string {
return x + y}
}
简写函数表达式(Function Expression)
let mySum = function (x: any, y:any): any {
return x + y;
}
完整函数表达式书写方式
let mySum: (x: number, y: number) => number = function (x: number, y: number): number {
return x + y;
}
类
修饰符
public:公共,在类/子类/示例中都可以访问
protected:保护类型的,只能在类和子类中访问,无法在实例中访问
proivate:私有
class Person {
}