typescript常用类型

// ts类型注解:约定了什么类型,就只能给变量赋值该类型的值

// js已有的类型:number/string/boolean/nul/undefined/symbol(生成唯一的标识) 对象类型:object

// ts原始类型:number/string/boolean 

let num1: number = 10

let num2: boolean = false

let num3: string = 'a'

// ts对象类型:数组类型number[](推荐写法), Array(写法react中会冲突)


 

// ts联合类型:数组中既可以有number也可以有string类型

let arr: (number | string)[] = ['a', 1]

// ts类型别名(自定义类型)

type CustomArray = (number | string)[] // let arr1: (number | string)[] = ['a', 1] => let arr2: CustomArray = ['a', 1]

//ts函数类型

function add1(num1: number, num2: number): number { //第一、二个number是给参数加类型,第三个是给返回值加类型

    return num1 + num2

}

add1(1, 2)

let add2 = (num1: number, num2: number): number => {

    return num1 + num2

}

add2(1, 2)

//ts函数空类型: 如果一个函数没有返回值,那么返回值类型为void

function greet(name: string): void {

    console.log('hello', name); // hello 各位同学

}

greet('中午好')

//ts函数的可选参数: 可选参数只能在必选参数之后

function mySlice(start?: number, end?: number) {

    console.log('起始索引', start, '结束索引', end);

}

mySlice()       // undefined / endefined

mySlice(1)      // 1 / undefined

mySlice(1, 5)   // 1 / 5

//ts对象类型

let person: { name: string; age: number; sayHi(name: string): void, add3: (num4: number, num5: number) => number } = {

    name: 'jack',

    age: 19,

    sayHi(name) {

        console.log('hello', name);

    },

    add3(num4, num5) {

        return num4 + num5

    }

}

//ts对象的可选属性:config可接收的参数,url请求地址,method请求方式为可选参数

function myAxios(config: { url: string; method?: string }) {

    console.log(config);

}

myAxios({ url: '' })

myAxios({ url: '', method: '' })

//ts接口:当一个对象类型被多次使用,一般会用接口(interface)来表示对象的类型

interface Iperson {

    name: string

    age: number

    sayHi(): void

}

let obj: Iperson = {

    name: 'rose',

    age: 28,

    sayHi() { },

}

//ts类型别名对比ts接口类型:都可以给对象指定类型  不同:接口只能为对象指定类型,类型别名可以为任意类型指定别名

// ts继承  如果两个接口之间有相同的属性或者方法,可以通过继承来复用

interface Point1 { x: number, y: number }

interface Point2 extends Point1 { z: number } //Ponit2同时有xyz三个属性

// ts元祖  元祖类型可以确切的标记出有多少个元素,以及元素对应的类型,可以用来记录位置信息

let position1: [number, number] = [39, 116]

let position2: [number, String] = [39, '116']

// ts类型推论  1.声明变量并初始化的时候 2.决定函数返回值的时候 =>这两种情况,类型注解可以省略,函数参数类型注解不可省略!

// ts类型断言  使用类型断言来指定更具体的类型

// const aLink = document.getElementById('link')

// aLink.href 会报错 // 这个类型太广泛,无法操作href等a标签特有的属性。

// 解决方法:使用类型断言指定更加具体的类型,HTMLAnchorElement是HTMLElement的子类型

const aLink1 = document.getElementById('link') as HTMLAnchorElement

// const aLink1 = document.getElementById('link') 不常用

aLink1.href

// ts字面量类型 除字符串外,任意js字面量(对象、数字)都可以作为类型使用

let srt1 = "hello"

const srt2 = "hello"

// 使用模式:字面量类型配合联合类型一起使用,用来表示一组明确的可选值列表

function changes(direction: 'up' | 'down' | 'left' | 'right') {

    console.log(direction); // direction值只有这4个中任意一个

}

// ts枚举类型

// 枚举or字面量+枚举 更推荐:字面量类型+联合类型 :高效,简洁,直观。枚举会再js中编译成对象形式

enum Direction { Up, Down, Left, Right }

function changedirection(direction: Direction) {

    console.log(direction);

}

changedirection(Direction.Up)

// 1.用enum关键字定义枚举 2.约定枚举名称,枚举中以大写字母开头,值用逗号隔开。3.定义枚举后直接用枚举名称作为类型注解

enum DIrection { Up = "Up", Down = "Down", Left = "Left", Right = "Right" }

//枚举成员的值为数字的枚举,称之为数字枚举,也可以给枚举中的成员初始化值。//字符串枚举每个成员必须要有初始值

// any类型:不推荐

//typeof 操作符,用来获取数据的类型,typeof只能用来查询变量或者属性的类型,无法查询其他形式的类型。

//ts 高级类型: class类、类型兼容性、交叉类型、泛型和keyof、索引签名类型和索引查询类型、映射类型

//class类

class person {

    age: number

    gender = "男"

    constructor(age: number, gender: string) { //构造函数没有返回值

        this.age = age  //this.age是person的实例属性,age是构造函数的参数

        this.gender = gender

    }

}

const p = new person(18, '男') //构造函数的作用 实例属性初始化

p.age  // 打印:18

p.gender // 打印:男

// class类继承两种方式:

// 1.extends(继承父类)

class Animal {

    move() {

        console.log('动一动');

    }

}

class Dog extends Animal {

    bark() {

        console.log('汪汪!');

    }

}

// 子类Dog继承父类Animal,则Dog的实例对象dog就同时具有了父类和子类所有的属性和方法

const dog = new Dog()

// 2.implements(实现接口)  PS:实现和继承不同,继承是class类与类之间的,实现是类和接口之间的关系,是ts特有的

interface Singable {

    sing(): void

}

class Person implements Singable {

    sing() {

        console.log('唱歌');

    }

} // Person类实现接口Singable意味着Person类中必须提供Singable接口中指定的所有方法和属性

// class类成员可见性  1.public:公有成员可以被任何地方访问,可省略 2.protected(受保护的):仅对其声明所在类和子类中(非实例对象)可见  3.private(私有的)

class Animal1 {

    //这个方法是受保护的

    protected move() {

        console.log('动一动');

    }

    private _run_() {

        console.log('Animal1 内部辅助函数');

    }

    run() {

        this.move() // 可以在当前类方法中通过this来调用

        this._run_() // 只可以在当前类方法中通过this来调用

        console.log('run');

    }

}

class Dog1 extends Animal1 {

    bark() {

        this.move() // 可以在子类方法中通过this来调用

        console.log('汪汪!');

    }

}

const a = new Animal1()

// a.move() 不可以通过实例对象访问

// class类 只读修饰符:readonly,只能修饰属性,不能修饰方法

// 注意:只要是用readonly来修饰属性的时候,必须手动提供明确的类型

class Person1 {

    age: number = 18

    constructor(age: number) {

        this.age = age

    }

    // readonly age: number = 18

    // constructor(age: number) {

    //     this.age = age

    // }

    setage() {

        this.age = 20 // 在没有只读修饰符的情况下,可以给age赋值,如果不想其他方法修改age的值,就加上只读修饰符

    }

}

interface Person1 {

    readonly name: string

}

// let obj: Person1 = {

//     name: 'jack'

// }

// let obj: { readonly name: string } = {

//     name: 'jack'

// }

// 类型兼容性

// ts采用结构化类型系统,如果两个对象具有相同的形状,认为他们属于同一类型

class point { x: number; y: number }

class point2 { x: number; y: number }

const p: point = new point2() //point与point2是两个名称不同的类,只是结构相同,所以没有类型错误,属于ts的类型兼容

// 对象之间的兼容

class point3 { x: number; y: number }

class point4 { x: number; y: number; z: number }

const p1: point3 = new point4() // point4兼容point3,成员多的可以赋值给成员少的

// 接口之间的兼容性

interface point3 { x: number; y: number }

interface point4 { x: number; y: number; z: number }

const p2: point3 = new point4()

const p3: point = new point3 //class和interface之间可以兼容,都是对象之间的兼容

// 函数之间的兼容性:参数个数,参数类型,返回类型

// 1.参数多的兼容参数少的(参数少可以赋值给多的) 2.参数类型:相同位置的参数类型要相同或兼容  3.返回值类型:只需要关注返回值类型本身即可

type F1 = (a: number) => void

type F2 = (a: number, b: number) => void

let f1: F1

let f2: F2 = f1

type F3 = (p: point3) => void  //相当于2个参数

type F4 = (p: point4) => void  //相当于3个参数

let f3: F3

let f4: F4 = f3 // 理解的时候可以将对象拆开,把每个属性看成一个个参数,参数少的可以赋值给参数多的

// 交叉类型 用于组合多个类型为一个类型

interface Person { name: string }

interface Contact { phone: string }

type PersonDetail = Person & Contact  // 新类型同时具备这两个类型的所有属性和方法

let Obj: PersonDetail = {

    name: 'jack',

    phone: '133...'

}

// 交叉类型(&)和接口继承(extends)的对比

// 相同点:都可以实现对象类型的组合       不同点:两种方式实现类型组合时,对于同名属性之间,处理类型冲突方式不同

interface A {

    fn: (value: number) => string

}

// interface B extends A {  // 接口继承  报错:类型不兼容

//     fn: (value: string) => string

// }

interface B {

    fn: (value: string) => string

}

type C = A & B  // 交叉类型

// 泛型 让函数等与多种类型一起工作,常用与函数、接口、class类中

// 语法:1.在函数名称后面添加<>,尖括号中添加类型变量,如Type  2.Type类型变量,是一种特殊类型的变量,它处理类型而不是值  3.该类型变量相当于一个类型容器,能够捕获用户提供的类型   4.因为Type是类型,因此可以将其作为函数参数和返回值的类型

function id(value: Type): Type { return value }

const num = id(10)  // 以number类型调用泛型函数

const str = id('a') // 以string类型调用泛型函数

// 简化调用泛型函数

let num1 = id(10)

let str1 = id('a')

// 泛型约束 需要为泛型添加泛型约束来收缩类型(缩小类型的取值范围)

// 1.指定更加具体的类型

function id1(value: Type[]): Type[] {

    console.log(value.length);

    return value

}

// 2.添加约束

interface Ilength { length: number }

function id2(value: Type): Type { // 这里的extends不是继承而是要求Type满足Ilength的属性

    console.log(value.length);

    return value

}

// 3.多个泛型变量

// keyof关键字接收一个对象类型,生成其键名称的联合类型

function getProp(obj: Type, key: Key) {

    return obj[key]

} // 函数中keyof Type实际上获取的是person对象所有键的联合类型,也就是'name|age',所以Key只能访问对象中存在的属性

let person = { name: 'jack', age: 18 } 

getProp(person, 'name')

你可能感兴趣的:(typescript常用类型)