原始类型使用
// 原始类型使用
let age: number = 18
let myName: string = '前端'
let isLoding: boolean = false
let a: null = null
let b: undefined = undefined
let s:symbol = Symbol()
数组类型使用
// 数组类型的两种写法
// 写法一
let numbers: number[] = [1, 2, 3] // 数值类型数组
// 写法二
let strings: Array = ['a', 'b'] // 不推荐写法,懂这种写法即可
联合类型使用
// 联合类型
// 数组中既有number类型又有string类型
const arr: (number | string)[] = [1, 'a']
// 不添加小括号,表示arr1既可以是number类型也可以是string[]类型
const arr1: number | string[] = 123;
类型别名(自定义类型)
// 类型别名(自定义类型)
type CustomArray = (number | string)[]
const arr: CustomArray = [1, 'a']
const arr1: CustomArray = ['111']
函数类型(单独指定参数和返回值的类型和同时指定参数和返回值的类型)
// 单独指定参数和返回值的类型
// 写法一
function add(num1: number, num2: number): number {
// (num1: number, num2: number)是指定参数类型
// 紧跟后面的: number是指定返回值的类型
return num1 + num2
}
console.log(add(1, 2));
// 写法二
const minus = (num1: number, num2: number): number => {
return num2 - num1
}
console.log(minus(1, 2));
// 同时指定参数和返回值的类型
// 1. 当函数作为表达式时,可以通过类似箭头函数形式的语法来为函数添加类型
// 2. 这种形式只适用于函数表达式
const add1: (num1: number, num2: number) => number = (num1, num2) => {
return num1 + num2
}
console.log(add1(11, 22));
void类型
// void类型
// 如果函数没有返回值,那么函数的返回值类型为void
function greet(name: string): void {
console.log(name)
}
greet('jack')
函数可选参数
// 函数可选参数
function mySlice(start?: number, end?: number): void {
console.log(start, end);
}
mySlice();
mySlice(1);
mySlice(1, 3);
对象类型
// 对象类型
let person: {
name: string
age: number
sayHi(): void
greet: (name: string) => void
} = {
name: 'jack',
age: 18,
sayHi() { },
greet: (name) => { }
}
对象可选属性
// 对象可选属性
function myAxios(config: { url: string; method?: string }) {
console.log(config)
}
myAxios({ url: '' })
接口(interface)
// 接口(interface)
interface IPerson {
name: string
age: number
sayHi(): void
}
let person: IPerson = {
name: '前端',
age: 35,
sayHi: () => { }
}
接口(interface)和类型别名(type)的对比
/**
* 接口(interface)和类型别名(type)的对比
*
* 相同点:都可以给对象指定类型
* 不同点:
* 1. 接口,只能为对象指定类型
* 2. 类型别名,不仅可以为对象指定类型,实际上可以为任意类型指定别名
*
*/
// 接口
// interface IPerson {
// name: string
// age: number
// sayHi(): void
// }
// 类型别名
type IPerson = {
name: string
age: number
sayHi(): void
}
let person: IPerson = {
name: '前端',
age: 35,
sayHi: () => { }
}
接口继承
// 接口继承
interface Point2D {
x: number
y: number
}
// 这样写麻烦有重复代码
// interface Point3D {
// x: number
// y: number
// z: number
// }
// 使用继承 实现复用
interface Point3D extends Point2D {
z: number
}
const p3: Point3D = {
x: 1,
y: 2,
z: 3
}
元组(场景:1. 在地图中,使用经纬度坐标来标记位置信息 2. 确切地知道包含多少索引以及类型时使用)
// 元组(场景:在地图中,使用经纬度坐标来标记位置信息)
// 不严谨,因为该类型number[]的数组中可以出现任意多个数字
// const position: number[] = [39, 11, 1, 2, 3]
// 更好的方式:元组(Tuple)
const position: [number, string] = [3, '4']
类型推论
// 类型推论(声明变量但没有初始化值,此时必须手动添加类型)
// 注意:能省略类型注解的地方就省略,充分利用TS类型推论的能力,提升开发效率
// 如果不知道类型,可以通过鼠标放在变量名称上,利用VSCode的提示来查看类型
let age = 18
// 类型保护机制也是存在的, 因此会报错
// age = ''
// 函数也是可以自动推论, 建议参数必须添加类型
function add(num1: number, num2: number) {
return num1 + num2
}
add(1, 3)
类型断言(使用场景:当明确标签类型时使用)
// 类型断言 链接
// 这种方法aLink类型时HTMLElement,
// const aLink = document.getElementById('link');
// console.log(aLink.href); // 获取不到
// 使用类型断言:
const aLink = document.getElementById('link') as HTMLAnchorElement;
console.log(aLink.href); // 可以获取到
字面量类型
// 字面量类型
let str1 = 'TS' // 类型是string
const str2 = 'TS' // 类型是'TS'
// 字面量类型应用场景: 比如贪吃蛇方向只能是上下左右
function changeDirection(direction: 'up' | 'down' | 'left' | 'right') {
console.log(direction);
}
changeDirection('down')
枚举类型
// 枚举类型
// 枚举:定义一组常量。他描述一个值,该值可以是这些命名常量中的一个
// 注意:枚举成员是有值的,默认为从0开始自增的数值
// 我们把枚举成员的值称为:数字枚举,我们也可以给枚举成员初始值
/**
* 枚举的特点及原理
*
*/
// // 设置数字枚举初始值
// enum Direction {
// Up = 10,
// Down = 11,
// Left = 12,
// Right = 13
// }
// 设置字符串枚举初始值
enum Direction {
Up = 'Up',
Down = 'Down',
Left = 'Left',
Right = 'Right'
}
let str1 = 'TS' // 类型是string
const str2 = 'TS' // 类型是'TS'
// 字面量类型应用场景: 比如贪吃蛇方向只能是上下左右
function changeDirection(direction: Direction) {
console.log(direction);
}
changeDirection(Direction.Up)
console.log(Direction); // {Up: 'Up', ...}
any类型(不推荐使用,会失去TS类型保护的优势)
// any类型(不推荐使用,会失去TS类型保护的优势)
let obj: any = { x: 0 }
// 不会显示错误信息
// obj.aaa = 10
typeof运算符
// typeof运算符
console.log(typeof 'TS') // string
let p = { x: 1, y: 2 }
function format(point: typeof p) { } // point类型是{x: number; y: number}
// 正确
format({ x: 1, y: 100 })
// 参数类型错误
// format(1)
let num: typeof p.x // num是number类型
function add(num1: number, num2: number) {
return num1 + num2
}
// 报错,因为不能查询函数调用后的类型
// let ret: typeof add(1, 2)
高级类型 - class类
// 1. class基本使用
class Son {
age: number
gender: string
constructor(age: number, gender: string) {
this.age = age
this.gender = gender
}
scale(age: number) {
this.age += age
}
}
const s = new Son(18, '男');
s.scale(10);
console.log(s.age, s.gender);
// 2. extends和implements
// 第一种方式:extends(继承) js
class Animal {
move() {
console.log('走两步');
}
}
class Dog extends Animal {
name = '二哈'
}
const d = new Dog();
d.move();
console.log(d.name);
---------------------------------------------------------------------------------------
// 第二种方式:implements(实现接口) ts
interface Single {
sing(): void
name: string
}
class Person implements Single {
name = 'jack'
sing() {
console.log('你是我的小苹果');
}
}
---------------------------------------------------------------------------------------
// 3. 可见性修饰符
// class 可见性修饰符
// public 表示公有的,公开的,公有成员可以被任何地方访问,默认可见性
class Animal {
public move() {
console.log('走两步');
}
}
const a = new Animal();
a.move(); // 可以访问
// protected 表示受保护的,仅对其声明所在类和子类中(非实例对象)可见
class Animal {
protected move() {
console.log('走两步');
}
run() {
this.move(); // 可以
}
}
// const a = new Animal();
// a.move(); // 不可以访问
class Dog extends Animal {
bark() {
this.move(); // 可以
}
}
const d = new Dog();
d.move(); // 不可以访问
// private 表示私有的,只在当前类中可见,对实例对象以及子类也是不可见的
class Animal {
private move() {
console.log('走两步');
}
run() {
this.move(); // 可以
}
}
// const a = new Animal();
// a.move(); // 不可以访问
class Dog extends Animal {
bark() {
this.move(); // 不可以访问
}
}
const d = new Dog();
d.move(); // 不可以访问
---------------------------------------------------------------------------------------
// 4. readonly
// readonly 表示只读,用来防止在构造函数之外对属性进行赋值
class Person {
readonly age: number = 18 // readonly修饰的,必须明确类型
constructor(age: number) {
this.age = age;
}
// readonly无法声明函数
// readonly setAge() {
// // 报错,无法赋值
// this.age = 20
// }
}
// 错误演示
class Person {
readonly age = 18 // 相当于常量18
constructor(age: number) {
this.age = age; // 无法赋值,无法赋值给类型18
}
// readonly无法声明函数
// readonly setAge() {
// // 报错,无法赋值
// this.age = 20
// }
}
// 接口案例一
interface IPerson {
readonly name: string
}
let obj: IPerson = {
name: 'jack'
}
// 无法赋值
obj.name = '2222'
// 接口案例二
let obj: {readonly name: string} = {
name: 'jack'
}
// 无法赋值
obj.name = '2222'