Typescript笔记

TypeScript

1.编译

需要编译成 es5 语法,浏览器才能识别

tsc index.ts # 会生成同名的js文件
tsc --init # 生成tsconfig.json
		   # 修改tsconfig.json的outdir
		   # vscode里 终端→运行任务→typescript→监视tsconfig.json

2.数据类型

本节内容包括:booleanstringnumberArray<T>[string,boolean]enumanyundefinednullnevervoid

let a: string = "你好呀,typescript!"
let b: number = 5
let c: boolean = false
// 数组定义的两种方式
let e1: number[] = [1, 2, 3, 4]
let e2: Array<number> = [1, 2, 3, 4]
let f: [string, number, boolean] = ["str", 12, false] // 元组类型,指定对应元素的类型
enum Flag { success = 1, failed = 0 } // 若 a,b=4,c 则a:0,b:4,c:5 - 枚举值根据上一个的枚举值+1
let g: Flag = Flag.success // g === 1

let h: any = document.getElementById("h1")
h.style.color = 'red'

let d: number | undefined | null
console.log(d);
function print():void{
    console.log("这个方法没有返回值");
}
print()
let n:never=(()=>{throw new Error("我也不知道它有啥用")})()

3.函数

本节内容包括:普通函数和匿名函数定义可选参数默认参数剩余参数函数重载箭头函数

function test1(): string {
    return "返回string"
}
var test2 = function (): string {
    return "匿名函数的用法"
}
function test3(name: string, age: number): string {
    return `我叫${name},我今年${age}岁!`
}
var test4 = function (name: string, age: number): void {
    console.log(`我叫${name},我今年${age}岁!`);
}
// 可选参数--可传可不传(注:必须在最后面,你应该懂得)
function test5(name: string, age?: number): void {
    if (age) {
        console.log(`我叫${name},今年${age}岁!`);
    } else {
        console.log(`我叫${name},年龄保密!`);
    }
}
// 默认参数
function test6(name: string, age: number = 20): void {
    console.log(`我叫${name},今年${age}岁!`);
}
// 剩余参数:数组参数,之前还有其他参数的话,按照顺序先赋值,剩余的赋值给数组
function test7(...arr: number[]): void {
    console.log(arr);

}
// 重载函数:es5中,下面的方法会覆盖上面的相同函数名????????????????????????
function test8(a:number ):string;
function test8(a:string ):string;
function test8(arg: any): any {
    if (typeof arg === 'string') {
        return arg + '-return string'
    } else {
        return arg + '-return number'
    }
}
console.log(test8("啊"));
console.log(test8(8));
// 箭头函数:
setInterval(() => {
    console.log('箭头函数没变化!');

}, 1000)

4.类

本节内容包括es5的内容:类的定义静态方法对象冒充继承原型链继承组合继承

"use strict";
function Person(name, age) {
    this.name = name
    this.age = age
    this.run = function () {
        console.log(this.name + "在跑步...");
    }
}
// 静态方法
Person.getInfo = function () {
    console.log("我是静态方法...");
}
// 原型对象上添加共享的属性和方法,类似于“类“
Person.prototype.sex = "男"
Person.prototype.work = function () {
    console.log(this.name + "在工作...");
}
// 调用
var p = new Person("罗志祥", 30)
p.run()
p.work()
Person.getInfo()
// 继承:对象冒充只会继承构造函数的内容,无法继承原型链上的
function Chinese() {
    Person.call(this)
}
var yy = new Chinese()
yy.age = 22
yy.name = "yy"
yy.run()
yy.work() // Error:work is not a function
// 原型链继承:既可以继承原型链的方法也可继承后遭函数的方法-但无法给父类传参
function Chinese() {
}
Chinese.prototype = new Person()
var yy = new Chinese() // 传参无效
yy.run() // undefined 在跑步...
yy.work() // undefined 在工作...

// 组合继承: 对象冒充继承父类的属性、方法、构造对象格式;原型链继承父类原型的属性、方法
function Chinese(name,age) {
    Person.call(this,name,age) // 对象冒充:可以继承构造函数的属性和方法,实例化子类
}
Chinese.prototype = Person.prototype // 再把Person的prototype的属性和方法继承下来
var yy = new Chinese('yy',20) // 传参有效
console.log(yy);
yy.run() // yy 在跑步...
yy.work() // yy 在运动...

本节部分包括的ts内容:类的定义继承类里面的修饰符静态属性和静态方法多态抽象类和抽象方法写法如下:

class Person {
    name: string
    age: number
    constructor(name: string, age: number) {
        this.name = name
        this.age = age
    }
    getName(): string {
        return this.name
    }
    setName(name: string): void {
        this.name = name
    }
    run(): void {
        console.log(this.name + '在跑步...');
    }
}
var p = new Person('', 22)
p.setName('yy')
p.run()
console.log(p);
// 类的继承
class Chinese extends Person {
    constructor(name: string) {
        super(name)
    }
    run(): void {
        console.log('子类:' + this.name + '在运动...');
    }
    work(): void {
        console.log(this.name + '在工作...');
    }
}
class Person {
    // protected:在类和子类中可访问;private:在类中可访问
    name: string // 默认是 public
    private age: number=0
    constructor(name: string) {
        this.name = name
    }
    setAge(age: number): void {
        this.age = age
    }
    getAge():number{
        return this.age
    }
    run(): void {
        console.log(this.name + '在运动...');
    }
}
class Person {
    // protected:在类和子类中可访问;private:在类中可访问
    name: string // 默认是 public
    private age: number = 0
    static type: string = 'human'
    constructor(name: string) {
        this.name = name
    }
    setAge(age: number): void {
        this.age = age
    }
    getAge(): number {
        return this.age
    }
    run(): void {
        console.log(this.name + '在运动...');
    }
    work(): void {
    }
    // 静态属性与静态方法
    static show(): void {
        console.log('我是静态方法...');
        console.log('只可访问静态属性-' + Person.type);
    }
}
// 多态:父类定义一个方法不去实现,子类各自实现自己的该方法
class Chinese extends Person {
    constructor(name: string) {
        super(name)
    }
    work(): void {
        console.log('中国人在工作...');

    }
}
class Japanese extends Person {
    constructor(name: string) {
        super(name)
    }
    work(): void {
        console.log('日本人在工作...');
    }
}

var yy = new Chinese('yy')
yy.work()
var xx = new Japanese('Akow')
xx.work()
// 抽象类和抽象方法:抽象方法只能放在抽象类中且不实现,子类必须实现
abstract class Animal {
    abstract eat(): void
}
class Dog extends Animal {
    name: string
    constructor(name: string) {
        super() // 必须调用这个
        this.name = name

    }
    eat(): void {
        console.log(this.name + '在吃东西...');
    }
}
var dog = new Dog('哈士奇')
dog.eat()

5.接口

定义:接口是一种规范的定义,定义了行为和动作的规范,起到一种限制和规范的作用

本部分内容包括:接口对参数限制接口参数可选类类型接口函数类型接口继承接口可索引接口(不常用)

// 对批量方法进行约束
// 对参数限制
interface FullName {
    firstName: string; // 注意分号结束
    secondName: string;
}
function printName(name: FullName): void {
    console.log(name.age);

    console.log(name.firstName + '-' + name.secondName);
}
var yy = {
    firstName: 'yu',
    secondName: 'yuan',
    age: 20
}
printName(yy)
// 传一个对象变量的时候,只需要包含firstName和secondName就行
// 我的理解:只会解析对象的firstName和secondName过去,虽然yy有age,但是方法内是拿不到的(针对ts,但js是可以直接打印的)
// 直接传一个对象,就只含firstName和secondName
interface FullName {
    firstName: string; // 注意分号结束
    secondName?: string; // 可选属性
}
    
// 函数类型接口:对方法传入的参数以及返回值进行约束
// 也就是说方法的参数和返回值必须按照接口来
interface formatInput {
    (name: string, age: number): string
}

var handleInfo: formatInput = function (name: string, age: number): string {
    return `我的名字叫${name},我今年${age}岁!`
}
console.log(handleInfo('张三', 20));
    
// 类类型接口:对类进行约束
interface Animal {
    name: string;
    eat(food: string): void;
}
class Dog implements Animal {
    name: string;
    constructor(name: string) {
        this.name = name
    }
    eat(): void {
        // 接口要求参数,但是这里不加参数也可以
        console.log(this.name + '吃东西...');

    }
}
var d = new Dog('哈士奇')
d.eat()

// 继承接口
interface Animal {
    eat(food: string): void
}
interface People extends Animal {
    work(name: string): void
}
class Chinese implements People {
    name: string
    constructor(name: string) {
        this.name = name
    }
    eat(food: string): void {
        console.log(this.name + '正在吃' + food);
    }
    work(name: string): void {
        console.log(this.name + '正在' + name);
    }
}
var yy = new Chinese('yuwan')
yy.eat('花甲米线')
yy.work('学习Typescript')

// 可索引接口:对数组、对象进行约束(不常用)
interface UserArr {
    [index: number]: string
}
var arr: UserArr = ['111', '222']
console.log(arr[0]);

6.范型

any相比,泛型支持类型校验,所以更好

本部分内容包括:范型定义泛型类泛型接口

// 定义范型
function getMyself<T>(a: T): T {
    return a
}
getMyself<number>(5)
getMyself<string>('ssss')

// 泛型类
class Custom<T>{
    nums: T[] = []
    push(value: T): void {
        this.nums.push(value)
    }
    min(): T {
        var minVal: T = this.nums[0]
        for (let i = 0; i < this.nums.length; i++) {
            if (minVal > this.nums[i]) {
                minVal = this.nums[i]
            }
        }
        return minVal
    }
}
var a = new Custom<number>()
a.push(1)
a.push(3)
console.log(a.min());

var b = new Custom<string>()
b.push('a')
b.push('f')
console.log(b.min());

// 泛型接口:两种写法
interface Iadd {
    <T>(a: T): T
}
var getData: Iadd = function <T>(a: T): T {
    return a
}
getData<number>(20)
getData<string>('20')

interface Iadd<T> {
    (a: T): T
}
function getData<T>(val: T): T {
    return val
}
var numGetData: Iadd<number> = getData
numGetData(20)
var strGetData: Iadd<string> = getData
strGetData('20')

// 利用泛型类实现添加用户表信息、其他表信息
class User {
    username: string
    password: string
    constructor(username: string, password: string) {
        this.username = username
        this.password = password
    }
}
class Goods {
    name: string
    price: number
    constructor(name: string, price: number) {
        this.name = name
        this.price = price
    }
}
class OptionClass<T>{
    insert(obj: T): boolean {
        console.log(obj);
        return true
    }
}
var op = new OptionClass<User>()
var yy = new User('yuwan', '123456')
op.insert(yy)

5-6综合运用

案例:封装MySQL、MongoDB、Mssql的底层库

要求:

  • 支持mysql、MongoDB、mssql
  • 各数据库都是增删查改操作
  • 注重接口规范、以及代码重用

注:泛型类才能实现范型接口

interface iDatabase<T> {
    insert(data: T): boolean;
    update(data: T, id: number): boolean;
    delete(id: number): boolean;
    query(id: number): boolean
}
// 注:泛型类才能实现泛型接口
class Mysql<T> implements iDatabase<T>{
    insert(data: T): boolean {
        console.log('插入成功...');
        console.log('插入的数据是:', data);
        return true

    }
    update(data: T, id: number): boolean {
        throw new Error("Method not implemented.");
    }
    delete(id: number): boolean {
        throw new Error("Method not implemented.");
    }
    query(id: number): boolean {
        throw new Error("Method not implemented.");
    }
};
class MongoDB<T> implements iDatabase<T>{
    insert(data: T): boolean {
        throw new Error("Method not implemented.");
    }
    update(data: T, id: number): boolean {
        throw new Error("Method not implemented.");
    }
    delete(id: number): boolean {
        throw new Error("Method not implemented.");
    }
    query(id: number): boolean {
        throw new Error("Method not implemented.");
    }
}
class User {
    username: string;
    password: string;
    constructor(username: string, password: string) {
        this.username = username
        this.password = password
    }
}

var user = new User('yuwan', '123456')
var opMysql = new Mysql<User>() // 限制参数是user表
opMysql.insert(user)

7.模块

感觉和es6的一样,没什么变化!

// user.ts
export class User {
    username: string;
    password: string;
    constructor(username: string, password: string) {
        this.username = username
        this.password = password
    }
}
// index.ts
import { User } from './user'
// ...

8.命名空间

命名空间:内部模块,主要用于组织代码,避免命名冲突

模块:Typescript的外部模块简称,侧重代码复用,一个模块可能有多个命名空间

namespace mysql {
    export var name: string = 'mysql的包...'
    export function insert(): void {
        console.log('mysql的操作方法...');
    }
}
namespace mongodb {
    export var name: string = 'mongodb的包...'
    export function insert(): void {
        console.log('mongodb的操作方法...');
    }
}
mysql.insert()
mongodb.insert()

9.装饰器

定义:是一种特殊类型的声明,可以附加到类声明、方法、属性和参数上,可以修改类的行为(类似Java的注解

常见分类:类装饰器、属性装饰器、方法装饰器、参数装饰器

写法:普通装饰器(无法传参)、装饰器工厂(可以传参)

本节内容包括:类装饰器的简单使用装饰器工厂装饰器重写类属性和方法属性装饰器方法装饰器

// 普通装饰器:扩展类的属性和方法,默认把class传过来
function Chinese(personClass: any) {
    personClass.prototype.work = function () {
        console.log(this.name + '在工作...');
    }
}

@Chinese
class Person {
    name: string;
    constructor(name: string) {
        this.name = name
    }
}
var yy: any = new Person('yuwan')
yy.work()
console.log(yy);

// 高级用法:类似于高阶函数,传入参数
function Chinese(params: string) {
    console.log(params);
    return function (personClass: any) {
        personClass.prototype.work = function () {
            console.log(this.name + '在工作...');
        }
    }
}
@Chinese('你想知道我在干什么吗?')
class Person {
    name: string;
    constructor(name: string) {
        this.name = name
    }
}
var yy: any = new Person('yuwan')
yy.work()
console.log(yy);
// 高级用法:装饰器重写类的属性和方法
function Chinese(personClass: any) {
    return class extends personClass {
        // 重载Person的属性和方法
        name = '哥哥'
        work(): void {
            console.log('装饰器:' + this.name + '在工作...');
        }
    }
}

@Chinese
class Person {
    name: string | undefined;
    constructor() {
        this.name = '罗志祥'
    }
    work(): void {
        console.log(this.name + '在工作...');

    }
}
var yy: any = new Person()
yy.work() // 哥哥在工作
console.log(yy); // yy是个匿名类了,继承了Person

// 属性装饰器
function log(message: string) {
    return function (target: any, propertyName: any) {
        // target :对于静态成员是类的构造函数,对于实例成员是类的原型对象 propertyName:属性名
        target[propertyName] = message
        console.log(target)
    }
}
class MyResponse {
    @log('初值...') // 未实例化类也会调用该方法
    message: string | undefined
}
var resp = new MyResponse()

// 方法参数器
function log(message: string) {
    return function (target: any, methodName: any, desc: any) {
        // target:类的静态成员来说是构造函数,实例成员来说是类的原型对象
        // methodName:方成员名
        // desc:成员属性描述符
        target.message = message
        target.run = function () { // 扩展类的成员
            console.log('running...');
        }
        // 总结:很像python的高阶函数,使得可以在这自定义调用原error()
        var origMethod = desc.value // 原方法体:function(...args){...}
        desc.value = function (...args: any[]) {
            console.log('装饰器执行前:',args);
            args=args.map(item => String(item))
            origMethod.apply(this, args) // 调用原来的error()方法
        }
    }
}
class MyResponse {
    message: string | undefined
    @log('嘻嘻')
    error(...args: any[]): void {
        console.log('装饰器执行后:', args);
    }
}
var resp: any = new MyResponse()
resp.error(123, 'aaa', true)
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值