TS常用类型

原始类型使用

// 原始类型使用
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'


你可能感兴趣的:(ts,typescript)