TypeScript基础知识总结

视频

黑马2020年前端热门教程推荐|五天从零基础学会TypeScript
TypeScript从入门到精通视频教程-2020年新版
个人认为先学第一个视频在学第二个
欢迎补充~

安装与运行

正常版

在这里插入图片描述
在这里插入图片描述

简化版

在这里插入图片描述
在这里插入图片描述

初体验

注释

单行注释

// content

多行注释

/* content */

输出语句

console.log(' content ')

变量和数据类型

什么是变量

变量是用来存储数据的容器,并且是可以变化的。

变量的使用

let age: number = 20
age = 21
console.log(age)

类型注解

类型注解是为变量添加类型约束的方式
约定了什么类型,只能给变量赋值什么类型的值。

静态数据类型

基础静态类型:number string null undefined boolean
对象静态类型:对象类型 数组类型 类类型 函数类型

null undefined

undefined 声明但未赋值的值
null 声明并且赋值,赋的值未null。

运算符

算术运算符

( + - * / )
+可实现字符串拼接

赋值运算符

= | += | -= | /= | *=

递增/递减运算符

++ | - -

比较运算符

逻辑运算符

&& ||

循环

for(let i: number = 0; i < 3; i++) {
    console.log(i)
}

数组

// 此数组只能存储字符串
let names: string[] = ['lyz', 'my']
console.log(names)

let per : (string|number)[] = ['lyz','my', 21]

// 类型别名
type Lady = {name: string, age: number}
let arr : Lady[] = [
    {name: 'lyz', age: 21},
    {name: 'my', age: 22}
]

元组

不常用

let arr : [string, number, string] = ['lyz', 21,'lyz']

函数

function sing(songName: string) {
    console.log(songName)
}
sing('有点甜')

// 函数返回值
function sum(number1: number, number2: number):number {
    return number1 + number2
}
let total = sum(1, 2)
console.log(total) 

// 参数为对象
function obj({one} : {one: number}) {
    return one
}
console.log(obj({one: 99}))

对象

类型注解

let person: {
    name: string;
    age: number;
    sayHi: () => void;
}
person = {
    name: 'lyz',
    age: 21,
    sayHi() {
        console.log('hi')
    }
}

接口

为对象的类型注解命名,并为你的代码建立契约来约束对象的结构

// height可有可无 any任意类型
let person: {
    name: string;
    age: number;
    height ?: number;
    [propname: string] : any;
    sayHi: () => void;
}
person = {
    name: 'lyz',
    age: 21,
    sex: 'nv',
    sayHi() {
        console.log('hi')
    }
}
console.log(p.sayHi(1))
interface Girl {
    name: string
}
let g = {
    name: 'lyz'
}
function say(g : Girl) {
    console.log(g.name)
}
say(g)

继承

interface IUser {
    name: string;
    age: number;
    sayHi: (number) => number;
}
interface Teacher extends IUser {
    teach: () => void
}
let te = {
    name: 'lyz',
    age: 21,
    sayHi(num) {
        return num
    },
    teach() {
        console.log('I am teacher')
    }
}
console.log(te.sayHi(99))
te.teach()

类型推论

在TS中,某些没有明确指出类型的地方,类型推论会帮助提供类型
发生类型推论的两种场景:1. 什么变量并初始化;2. 决定函数返回值时。

class Person {
    content = 'hello'
    sayHi() {
        return 'hi'
    }
}

class Girl extends Person {
    sayHi() {
        return super.sayHi() + ' world'
    }
    dance() {
        console.log('i can dance')
    }
}

const g = new Girl()
console.log(g.sayHi())
g.dance()

访问类型

public 类的内部和类的外部都能使用
protected 类的内部使用(继承中可使用)
private 只能在类的内部使用(继承中也不可能)

构造函数

class Person {
    public name: string
    constructor(name: string) {
        this.name = name
    }
}

继承中必须写super()

//简化
class Person {
    constructor(public name: string) {}
}
class Teacher extends Person {
    constructor(public age: number) {
        super('lyz')
    }
}
const per = new Teacher(21);
console.log(per.name)
console.log(per.age)



class Person {
    constructor(public name: string) {}
}
class Teacher extends Person {
    constructor(public name: string, public age: number) {
        super(name)
    }
}
const per = new Teacher('lyz', 21);
console.log(per.name)
console.log(per.age)

Getter Setter static

class Girl {
    constructor(private _age: number) {}
    get age() {
        return this._age-10
    }
    set age(age: number) {
        this._age = age + 7
    }
}
let girl = new Girl(21)
console.log(girl.age) // 11 返回的值为getter中的值
girl.age = 22 // 设置的是setter中 此时age为29 [22+7]
console.log(girl.age) // 19 [29-10] 

静态类

无需实例化对象,就可以直接调用类中的方法。

class Person {
    static sayHi() {
        console.log('hi')
    }
}
Person.sayHi()

只读属性

class Girl {
    public readonly _name: string
    constructor(name: string) {
        this._name = name
    }
}
let girl = new Girl('lyz')
// girl._name = 'my' 不可对_name进行修改
console.log(girl._name)

抽象类

必须要重写抽象方法 否则会报错

abstract class Person {
    abstract say()
}
class Girl extends Person {
    say() {
        console.log('say boy')
    }
}
class Boy extends Person {
    say() {
        console.log('say girl')
    }
}

tsconfig.json文件

//tscongif起作用
tsc

联合类型和类型守护

interface Student {
    doing: false
    say: () => void
}
interface Teacher {
    doing: true
    take: () => void
}
function who(per: (Student | Teacher)) {
    if(per.doing) {
        (per as Teacher).take()
    } else {
        (per as Student).say()
    }
}
who({doing: true, take(){console.log('take')}})
interface Student {
    doing: false
    say: () => void
}
interface Teacher {
    doing: true
    take: () => void
}
function who(per: (Student | Teacher)) {
    if('say' in per) {
        per.say()
    } else {
        per.take()
    }
}
who({doing: false, say(){console.log('say')}})
function add(first: (string | number), second: (string | number)) {
    if(typeof first === 'string' || typeof second === 'string') {
        return `${first}${second}`
    }
    return first +second
}
console.log(add('9', 9))
console.log(add(9, 9))
class NumObj {
    constructor(public count: number){}
}
function add(first: NumObj | object, second: NumObj | object) {
    if(first instanceof NumObj && second instanceof NumObj) {
        return first.count + second.count
    }
    return 0
}
let first = new NumObj(1)
let second = new NumObj(1)
console.log(add(first,second))

枚举

enum Dream {
    House, 
    White,
    Beauty
}
function getDream(dream: any) {
    if(dream === Dream.White) {
        console.log("White")
    } else if (dream === Dream.House) {
        console.log("House")
    } else if (dream === Dream.Beauty) {
        console.log("Beauty")
    }
}
getDream(1)
console.log(Dream.White, Dream[1])  //1 'White'
console.log(Dream.House) // 0
console.log(Dream.Beauty) // 2

泛型

在函数调用时确定类型

函数

function add<T>(first: T, second: T) {
    return `${first}${second}`
}
console.log(add<string>('m', 'y'))
function getArr<T>(arr: Array<T>){
    return arr
}
console.log(getArr<number>([1, 2]))

function getArray<T>(arr: T[]){
    return arr
}
console.log(getArray<string>(['9', '9']))
function add<T, P>(first: T, second: P) {
    return `${first}${second}`
}
console.log(add<string, number>('m', 1))

class SelectGirls<T> {
    constructor(public girl: T[]) {}
    getGirl(index: number) {console.log(this.girl[index])}
}
let g = new SelectGirls(['lyz', 'glnz', 5])
g.getGirl(2)

继承

interface Girl {
    name: string
}

class SelectGirls<T extends Girl> {
    constructor(public girl: T[]) {}
    getGirl(index: number):string {return this.girl[index].name}
}
let g = new SelectGirls([
    {name: 'lyz',age: 21},{name: 'my',age: 22},{name: 'lyj',age: 11}
])
console.log(g.getGirl(2))

命名空间

// html页面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./build/page.js"></script>
</head>
<body>
    <script>
        new Home.Page()
    </script>
</body>
</html>

// ts文件
//components.ts
namespace Components {
    export class Header {
        constructor() {
            const elem = document.createElement('div')
            elem.innerText = 'Header'
            document.body.appendChild(elem)
        }
    }
    export class Content {
        constructor() {
            const elem = document.createElement('div')
            elem.innerText = 'Content'
            document.body.appendChild(elem)
        }
    }
    export class Footer {
        constructor() {
            const elem = document.createElement('div')
            elem.innerText = 'Footer'
            document.body.appendChild(elem)
        }
    }
}
//page.ts
namespace Home {
    export class Page {
        constructor() {
            new Components.Header()
            new Components.Content()
            new Components.Footer()
        }
    }
}

装饰器

装饰器是一种特殊类型的声明,它能够被添加到类声明,方法、属性或参数上,可以修改类的行为。
常见的装饰器:类装饰器、属性装饰器、方法装饰器、参数装饰器。
装饰器的写法:普通装饰器(无参数)、装饰器工厂(可传参)。

类装饰器

// 普通装饰器
function logClass(params: any) {
    console.log(params)
    params.prototype.apiurl = '动态扩展属性'
    params.prototype.say = function() {
        console.log('say')
    }
}

@logClass
class HttpClient {
    constructor() {}
}

let h = new HttpClient()
console.log(h.apiurl)
h.say()

// 装饰器工厂
function logClass(params: string) {
    return function(target: any) {
        console.log(target)
        console.log(params)
        target.prototype.uname = params
    }
}
@logClass('lyz')
class HttpClass {
    constructor() {}
}
let h = new HttpClass()
console.log(h.uname)

类装饰器会在运行时被当做函数调用,类的构造函数作为唯一的参数。
如果装饰器返回一个值,他会使用提供的构造函数来替换类的声明。

// 类装饰器重载构造函数
function logClass(params: any) {
    return class extends params {
         uname: any = '我是修改后的uname' 
         getUname(){
            this.uname = this.uname +'-------'
            console.log(this.uname)
         }
    }
}
@logClass
class HttpClass {
    public uname: string | undefined
    constructor() {
        this.uname = 'uname'
    }
    getUname() {
        console.log(this.uname)
    }
}
let h = new HttpClass()
h.getUname()

属性装饰器

属性装饰器会在运行时当做函数被调用,传入两个参数:

  1. 对于静态成员来说是类的构造函数,对于实力成员是类的原型;
  2. 成员的名字。
function logParam(params:any) {
    return function(target: any, attr: any) {
        console.log(target)
        console.log(attr) // uname
        target[attr] = params
    }
}

class LogCons {
    @logParam('lyz')
    public uname: any
    constructor() {}
    getName() {
        console.log(this.uname) // lyz
    }
}
let h = new LogCons()
h.getName()

方法装饰器

方法装饰器会被应用到方法的属性描述符上,可以用来监视,修改或替换方法定义。
方法装饰器会在运行时传入下列三个参数:

  1. 对于静态成员来说是类的构造函数,对于实力成员是类的原型;
  2. 成员的名字;
  3. 成员的属性描述符。
    这里是引用。
function get(params: any){
    return function(target: any, getMethodName: any, desc: any) {
        console.log(target)
        console.log(getMethodName)
        console.log(desc)

        target.api = 'xxx'
        target.run = function(){
            console.log('run')
        }
    } 
}
class GetFun {
    public url: any | undefined
    constructor(){}
    @get('lyz')
    getName() {
        console.log(this.url)
    }
    getAge(){}
} 
let g = new GetFun()
console.log(g.api)
g.run()
g.getName()
// 修改
function get(params: any){
    return function(target: any, getMethodName: any, desc: any) {
        console.log(target)
        console.log(getMethodName)
        console.log(desc.value)
		
		// 把当前参数修改为string类型
        // 保存当前方法
        let oMethod = desc.value
        desc.value = function(...arg: any[]){
            arg = arg.map( ele =>{
                return String(ele)
            })
            console.log(arg)

            oMethod.apply(this, arg)
        }
    } 
}
class GetFun {
    public url: any | undefined
    constructor(){}
    @get('lyz')
    getName(...arg: any[]) {
        console.log(arg)
    }
    getAge(){}
} 
let g = new GetFun()

g.getName(99, 11, 23)

方法参数装饰器

方法参数装饰器表达式会在运行时当做函数被调用,可以使用方法参数装饰器为类的原型增加一些元素数据,传入下列三个参数:

  1. 对于静态成员来说是类的构造函数,对于实例成员是类的原型;
  2. 方法的名称;
  3. 参数在函数参数列表中的索引。
function get(params: any){
    return function(target: any, methodName: any, paramsIndex: any) {
        console.log(target)
        console.log(methodName)
        console.log(paramsIndex)

        console.log(params)
        
    } 
}
class GetFun {
    public url: any | undefined
    constructor(){}
    getName(@get('nname')uname: any) {
        console.log(uname)
    }
} 
let g = new GetFun() 
g.getName('lyz')

执行顺序

同一类型从右向左(从下向上)
不同类型:属性装饰器>方法装饰器>方法参数装饰器>类装饰器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值