TypeScript

193 阅读5分钟

基础类型

let a:number = 1 / NaN / Infinity
let b:string = '1' / `a`
let c:boolean = true
let d:undefined = undefined
let e:null = null

void

let a:void = undefined
let b:void = null

// void与undefined/null区别
1. 不能给子类赋值;
2. 可以相互赋值;


function fn():void {} // 不能有返回值

任意类型 any unknown

let anys:any = 'aaa'
anys = 任意类型
any可以赋值任意类型

let un1:unknown = 1
let un2:unknown = { a: 1 }

un1 = '1' // 报错
un2.a = '1' // 报错

不可以赋值其他类型;
不可以使用内部属性和方法;
不可能充当其他类型的子类型;
只能赋值自身或者any类型

let anys:any = 'aaa'
let un1:unknown = 1

定义对象 interface ?: [propName:string]:any readonly void extend

interface A {
    name: string
}
interface A {
    age: number
}
// 相同名字的类型会进行合并
// 相当于extend
interface A {
    name: string
}
interface B extend A {
    age: number
}

interface B {
    name: string,
    age?: number
}
// 可选配置符

interface C {
    a:number,
    c:number,
    d:string,
    ...
    [propName:string]:any 
}
// 对与未知类型配置的任意类型,可以配合联合类型使用

interface C {
    readonly a:number,
    c:number,
    d:string,
    ...
    [propName:string]:any 
}
// readonly 配置后属性变为只读

interface C {
    readonly a:number,
    c:number,
    cb:void 
    [propName:string]:any 
}
// void定义没有返回值

定义数组:

常规声明

let arr: number[] = [1,2,3,4]
let arr: string[] = ['1','2']
let arr: boolean[] = [true, false]
let arr: any[] = [true, 1, 'aaa', [], {}]

let arr:number [][][] = [[[]], [[]], [[]]]

泛型声明:

let arr:Array<number> = [1, 2, 3]
let arr:Array<string> = ['aa']

let arr:Arrary<Array<number>> = [[1,2],[3,4]]

类数组关键字Iarguments

function Arr(...args:any):void {

    let arr:Iarguments = arguments

}

Arr(1,2,3,4)

接口定义

interface ArrNumber {
    [index:number]: number
}

let arr: ArrNumber = [1,2,3]

函数扩展

interface User {
    name: string,
    age: number
}

const fn1 = function(user: User): User {
    return user
}
fn1({name: 'tom', age: 16})


const fn2 = function(name:string, age:number):string {
    return name + age
}
fn1('joker', 16)

重载函数

// 前两个为重载函数,最后一个为执行函数,遵循任意一个重载函数的规则
function fn(params:number):void
function fn(params:string, params2:number):void
function fn(params:any,params2?:any):any {
    console.log(params, params2)
    return params + params2
}

fn(1) // 1, undefined
fn('aa', 2) // 'aa', 2

联合声明 |

let aa:number | string = 111 / 'bbb'

// 应用
let fn = function (type:number | boolean):boolean {
    return !!type
}

fn(1) // true
fn(false) // false

交叉类型 &&

interface Pop {
    name: string
}
interface Age {
    age: number
}

const fn = (man:Pop && Age):void => {
    console.log(man)
}

fn({name: 'Tom', age: 12}) // {name: 'Tom', age: 12}

类型断言 as

let fn = function (num:number | string):void {
    console.log((num as string).length)
    // 简写 <string>num.length
    console.log(<string>num.length)
}

fn('aaaa') // 4
fn(12344) // undefined
// 只能欺骗typescript,不能避免类型错误出现

内置对象

RegExp Date Error

const regexp:RegExp = /\w\d\s/ // 正则
const date: Date = new Date() // 日期
const error: Error = new Error('') // 

DOM BOM内置对象

DOM
const list:NodeList = document.body.querySelectorAll('#list li')
const body:HTMLElement = document.body
const div:HTMLDivElement = document.querySelector('div')

BOM
document.addEventListenter('click',(e:MouseEvent) => {
    console.log(e)
})
founction promise():Promise<number> {
    return new Promise<number>((resolve, reject) => {
        resolve(1)
    })
}
promise().then(res => {
    log(res)
})

Class类

类型修饰符 public private protected implements

class Person {
    public name:string // 默认public
    private age:number // private
    static aaa:string = 'bbbb' // static
    // 类型与变量一一对应
    constructor(name:string, age:number) {
        this.name = name
        this.age = age
        // 不能调用static声明的函数
    }
    static run() {
        // 内部只能访问static属性, 访问不了constructor内部变量
        this.aaa
    }
}

let p = new Person('Tom', age)

public 表示内外都能访问 p.name // Tom
private 表示私有属性,只能内部访问 
protected 也是只能内部访问,子类内可以访问
static 静态属性,不需要new关键字也能访问 Person.aaa // 'bbb'


// implements
interfac Pp {
    run(type: boolean):boolean
}
interfac Ph {
    set():void
}

class Man implements Pp,Ph {
    run(type: boolean): boolean{
        return type
    }
    set() {}
}

抽象类 abstract

abstract class A {
    name:string
    construstor(name:string) {
        this.name = name
    }
    
    abstract getName() {}
    setName(name: string) {
        this.name = name
    }
    // 带有abstract声明的函数不能直接含有数据处理
}

class B extends A {
    constructor() {
        super('aaa')
    }
    getName():string {
        return this.name
    }
}

let b = new B()

console.log(b.getName())

元组类型

let arr:[string, number] = ['aa', 123]

// 声明之后只能按照类型填充元素,不允许添加元素
// 场景:excel:[string,string,number][] = [
    ['', '', 1]
]

枚举 enum

enum Aa {
    aa,
    bb,
    cc
} 
// 0,1,2
log(Aa.aa) // 0

// 增长枚举
enum Aa {
    aa = 1,
    bb,
    cc
}
// 1,2,3
log(Aa.aa) // 1

// 自定义枚举
enum Aa {
    aa = 1,
    bb = 1,
    cc = 1
}

// 字符串
enum Aa {
    aa = 'a',
    bb = 'b',
    cc = 'c'
}

// 异构枚举
enum Aa {
    aa = 'a',
    bb = 22,
    cc = 'c'
}

interface A {
    red:Aa.aa
}
let obj:A = {
    red:Aa.aa // 必须与interface上对应上
}

const 枚举

const enum Type {
    ss,
    ff
}

let cc:number = 0

if(cc === Type.ss) {}

const 声明的枚举编译成js的时候会直接编译为常量,其他的会声明为对象

反向映射

enum Type {
    ss,
    cc
}

let key = Type[Type.ss]
log(key) // ss

类型别名

type s = string
type sb = string | boolean
type t = 'off' | 'on' | false | 111

let aa:s = 'a'
let bb:sb = true
let cc:t = 'off' / 'on' / false / 111

naver类型

// 表示永远不可能达到的

function error(message:string):naver {
    throw new Error(message) // 抛出报错,永远不会有返回值
}

interface A {
    aa: 'a'
}
interface B {
    bb: 'b'
}

type All = A | B

function type(val:All) {
    switch (val.type) {
        case 'a':
            brack
        case 'b':
            brack
        default:
            const check:naver = val
            brack
    }
}

Symbol类型

let aa:symbol = Symbol('123')
let bb:symbol = Symbol(123)
let cc:string = ('c')

let obj = {
    [aa]: 'a',
    [bb]: 'b',
    cc: 'c'
}

for(let key in obj) {
    log(key) // 不会循环symbol类型
}

需要循环含有symbol类型的全部数据可以使用
Object.getOwnPropertySymbol(obj)
Reflect.ownKeys(obj)

symbol.Iterator 迭代

type mapKey = string | number
let arr:Array<number> = [4,5,6]
let set:Set<number> = new Set([1,2,3])

let map: Map<mapKeys, mapKeys> = new Map()
map.set('1', 'a')
map.set('2', 'b')

function gen(erg:any) {
    let it:Iterator<any> = erg[Symbol.iterator]()
    let next: any= { done: false}
    while (!next.done) {
        next = it.next()
        if(!next.done) {
           console.log(next)
        }
    }
}

gen(arr)

泛型

// 先用自定义变量名代替类型,调用时传入类型

function add<T>(a:T, b:T):Array<T> {
    return [a, b]
}
add<string>('a','b')
add<number>(1, 2)

// 多个类型
function add<T, U>(a:T, b:U):Array<T | U> = [a, b] {
    let arr:Array<T | U> = [a, b]
    return [a, b]
}
add<string, number>('a', 2)

// 泛型约束
interface Len {
    length:number
}
function getLength<T extends Len>(arg:T) {
    return arg.length
}

getLength('aaa') // 只能穿带有length属性的参数

keyof

通过使用extends继承泛型的子类型,然后keyof获取到继承来的子类型的key返回的是联合类型,最后通过extends关键字约束key的泛型必须为keyof联合类型的子类型

fonction pp<T, K extends keyof T>(obj:T, key:K) {
    return obj[key]
}

pp({ aa: 'a', bb: 'b' }, 'bb') // 'b'
pp({ aa: 'a', bb: 'b' }, 'cc') // 提示没有这个key

Class

class Ss<T> {
    attr: T[] = []
}

let arr = new Ss<number>() // 指定泛型类型
arr.attr = [1,2,3]

ts.config.js

命名空间 ``

namespace A {
    export const a = 1
}
// 可以嵌套

log(A.a)

抽离命名空间

export namespace A {
    export const a = 1
}

使用 import { A } from ''

重新命名 import B = A.a

三斜线指令

namespace A {
    export const a = 1
}

///<referebce path="index1.ts">

声明文件 declare

1.
新建express.d.ts
declare var express:() => any

2.
npm 安装

混入 Mixin

对象
interface Name {
    name: string
}
interface Age {
    age:number
}

let a: Name = { name: 'Tom' }
let b: Age = { age: 16 }

let obj = Object.assign(a, b) // type Name & Ageclass A<T> {
    type:T
    changeType():void {
        this.type = !this.type
    }
}
class B<U> {
    name:U
    getName():U {
        return this.name
    }
}

class C implements A,B {
    type:boolean = false
    name:string = 'Tom'
    changeType:() => void
    getName:() => string
}

mixixs(C, [A,B])
function mixixs(curClass:any, itemsClass:any) {
    itemsClass.forEach(item => {
        Object.getOwnPropertyNames(item.prototype).forEach(name => {
            curClass.prototype[name] = item.prototype[name]
        })
    })
}

装饰器 Decorator @

const watcher = (name: <T>):ClassDecorator {
    return (target:Function) = {
        target.prototype.getName = (name) => {
            console.log(name)
        }
    }
}

@watcher
class A {}

let a = new A()
<any>a.getName('aaa') // 'aaa'