zoukankan      html  css  js  c++  java
  • typescript 学习笔记

    在用typescript进行开发的时候用npm package.json进行配置的时候用如下进行快速构建:

    1、配置环境参看webpack,  (需要安装typescript 与 ts-loader, 项目初始化的时候 tsc --init进行初始化,并且生成tsconfig文件)

    2、typescriptr的基础类型(通过例子说明)

    //布尔类型
    let bool1: boolean = true;
    let bool2: boolean;
    //数值类型
    let num1: number = 123;
    let num2: number;
    //字符串类型
    let str1: string = 'are you ok???';
    let str2: string;
    //数组类型
    let arr1: number [] = [1, 2, 3];
    let arr2: Array<number|string> = [1, 'test', 3];
    let arr3: (number|string|boolean)[] = [];
    let arr4: Array<string> | Array<number>;
    //元组类型(与数组的区别在于元组必需全部元素类型都一致,并且一个都不能少)
    let yArr1: [string, number, boolean];
    yArr1 = ['test', 2, true];
    //枚举类型, 一般枚举名称第一个字母为大字
    enum Role {
        AAA,
        BBB,
        CCC
    }
    console.log(Role.AAA, Role.BBB, Role.CCC);
    //也可以对枚举类型进行指定
    enum Role2{
        A = 1,
        B = 3,
        C = 5
    }
    console.log(Role2.A, Role2.B, Role2, Role2[1]);
    
    enum Role3 {
        FIRST = Role2.A,
        SECOND = Role2.B
    }
    console.log(Role3);
    
    //any 类型
    let any1: any = [1, 'test'];
    let any2: any = 'test';
    
    //void 类型
    //没有返回值的函数
    let func = (...rest: Array<string|number|boolean|Function>): void => {
        console.log(rest);
    };
    func('aaa', 1, true);
    
    //null 和 undefined 类型
    let u: undefined = undefined;
    let n: null = null;
    
    //never类型  抛出错误的时候可用或者是死循环的时候可以用never类型
    let errorFun = (msg: string): never =>{
        throw new Error(msg);
    };
    
    //object 类型
    let obj1: {key: string, val: number} = {'key': 'abc', 'val': 10};
    let obj2: object = {};
    //map类型
    let m1: Map<string, number> = new Map<string, number>();
    m1.set('aaa', 20);
    console.log(m1, m1.get('aaa'));
    
    //set 类型
    let s1: Set<string | number> = new Set<string | number>();
    s1.add('haha');
    s1.add(123);
    console.log(s1);

     小技巧,如果想用已经定义好的变量的值引入对象中,那么需要用'[]'来修饰

    enum Type {
        FIRST,
        SECOND,
        THIRD
    }
    let test: string = 'haha';
    //对象中使用已定义好的类型
    let json: object = {
        [Type.FIRST]: 'aaa',
        [Type.SECOND]: 'bbb',
        [Type.THIRD]: 'ccc',
        [test] : 'ddd'
    };
    console.log(json);
    //输出 {0: "aaa", 1: "bbb", 2: "ccc", haha: "ddd"}
    
    interface IFix {
        type: Type
    }
    
    //如果继承了以上的接口,那么说明里面的值必需是Enum里的值
    let obj: IFix = {
        type: Type.FIRST,
        // type: Type.SECOND
    };
    
    //枚举类型中引用枚举类型
    enum Check {
        GET = Type.FIRST,
        SET = Type.SECOND
    }
    console.log(Check);
    //定义对象的类型
    let obj1: {[key: number]: string|number} = {0: 'aaa', 1: 'bbb', 3: 4};
    //定义好数组对象的混合类型
    let arr1: Array<{[key: number]: string}> = [{
        1: 'a',
    }];

    3、类型断言

    /**
     * 类型断言(有两种写法)
     * 一种用(<string>target)
     * 一种用(target as string)
     */
    let getLength = function(target: string | number): number {
        if((<string>target).length) {           
            return (target as string).length;
        } else {
            return target.toString().length;
        }
    };

     4、Symbol对象的使用

    let s1 = Symbol('test');
    let s2 = Symbol('test');
    console.log(s1 === s2);
    //输出 false; 因为两者是唯一的
    let obj: object = {
        [s1]: 'abc',
        [s2]: 'efg'
    };
    console.log(obj);
    //输出 {Symbol(test): "abc", Symbol(test): "efg"}
    //这种属性在object里面只能通过obj[s1]或者obj[s2]来访问,或者通过Object.getOwnPropertySymbols(obj)来获取全部的,其它的方式是不能访问到的
    
    console.log(Object.getOwnPropertySymbols(obj));
    //输出 [Symbol(test), Symbol(test)]
    
    
    //Symbol.for(key)表示会在全局搜索是否有check的Symbol对象,如果有,则返回创建好的对象,如果没有,那么就自行创建一个
    let s3 = Symbol.for('check');
    let s4 = Symbol.for('check');
    console.log(s3 === s4);     //返回true
    
    //Symbol.keyFor(symbolObject);
    console.log(Symbol.keyFor(s3));  //输出 check

     5、接口类型

    //对象的接口化
    interface IArgs {
        name: string,           //常规属性
        age?: number,           //可选属性
        readonly sex: boolean,  //只读属性
    }
    //实现传入的参数接口化
    let getInfo = (msg: IArgs): string => {
        return `my name is ${msg.name}, ${msg.age? "我今年是" + msg.age+ "岁了,": ''} 我的性别是msg.sex`;
    };
    
    console.log(getInfo({
        name: 'aaaa',
        age: 22,
        sex: true
    }));
    
    interface IObj {
        [key: number]: string
    }
    let obj2: IObj = {0: 'aaa', 1: 'bbb'};
    
    interface IObject {
        age?: number,
        name: string,
        [name: number]: boolean
    }
    let o: IObject = {
        1: true,
        age: 12,
        name: 'get',
    };
    
    //数组接口化
    interface IArr {
        0: number,
        readonly 1: string,
        2: boolean
    }
    
    let arr: IArr = [1, 'abc', false];
    
    //接口函数化
    interface IFunc {
        (name: string, age: number): string
    }
    
    let introduce: IFunc = function(name: string, age: number): string {
        return 'this is test';
    };
    
    console.log(introduce('test', 12));
    
    //注意区别非接口化的类型指定
    let introduce1: (name: string, age: number) => string = (name: string, age: number): string => {
        return 'this is also test';
    };
    
    //接口可以实现继承
    interface IFirst {
        name: string
    }
    
    interface ISecond extends IFirst {
        age?: number,
        sex: number;
    }

     6、函数

    //可选参数用?来表示
    let func1: (a: number, b: number, c?: number) => number = (a: number, b: number, c?: number) : number => {
        return a+b;
    };
    console.log(func1(1,2));
    
    //使用参数的默认值用=来表示
    let func2: (name: string, age: number, dis: string) => string = (name: string, age: number, dis: string = 'test'): string => {
        return `${dis},name${name}, age: ${age}`;
    };
    console.log(func2('aaa', 30, 'instroduce'));
    
    //使用剩余参数
    let func3 = (n1: number, n2: number, ...ns: number[]): number => {
        let sum = 0;
        ns.forEach(value => sum +=value);
        return n1 * n2 + sum;
    };
    
    console.log(func3(1,2,3,4));

     7、泛型

    //泛型函数一
    function func1<T>(sign: T): T {
        return sign;
    }
    console.log(func1('check'));
    
    //泛型函数二
    let func2: <T>(name: string, age: T) => string = <T>(name: string, age: T): string => {
        if(typeof age === 'number') {
            return '' + age;
        }
        return `${name}, ${age}`;
    };
    //确定类型的泛型函数的调用
    console.log(func2<string>('test', 'unknow'));
    
    //泛型函数三
    //返回的是由泛型构成的数组
    let func3: <T>(key: T, times: number) => T[] = <T>(key: T, times: number): Array<T> => {
        return new Array(times).fill(key);
    };
    
    //调用
    console.log(func3<number>(8, 6));
    //输出 (6) [8, 8, 8, 8, 8, 8]
    
    
    //指定泛型属性
    interface IT {
        length: number
    }
    
    let func4: <T extends IT> (key: T) => number = <T extends IT>(key: T): number => {
        return key.length;
    };
    
    console.log(func4('are you ok???'));
    console.log(func4([1,2,3]));
    console.log(func4({length: 6}));
    
    //属性值的泛型指定
    let func5: <T, K extends keyof T> (obj: T, props: K) => any = <T, K extends keyof T>(obj: T, props: K) => {
        return obj[props];
    };
    
    console.log(func5({name: 'aaa'}, 'name'));
    //console.log(func5({name: 'aaa'}, '')); 会报错
    
    //接口中用泛型表示的方法有两种
    interface ITest <T>{            //这种表示方法则表示里面的全部适用泛型
        (name: string, age: number, type: T): string,
        (arr: Array<T>): T[]
    }
    //这种方法则表示,只是里面声明行的是泛型
    interface ICheck {
        <T>(name: T, age: number): string,
        (arr: Array<string>): string
    }
    let func = <T,U>(obj1:T, obj2: U): T & U => {
        // let obj = {} as T & U;      //类型断言
        // obj = Object.assign(obj1, obj2);
        // return obj;
        return Object.assign(obj1, obj2);
    };
    interface Obj<T> {
      [key: number]: T;
    }
    const key: keyof Obj<number>; // keys的类型为number
    //这里需要注意,在讲接口一节时,讲索引类型的时候我们讲过,如果索引类型为 number,那么实现该接口的对象的属性名必须是 number 类型;但是如果接口的索引类型是 string 类型,那么实现该接口的对象的属性名设置为数值类型的值也是可以的,因为数值最后还是会先转换为字符串。这里一样,如果接口的索引类型设置为 string 的话,keyof Obj<number>等同于类型number | string:
    
    interface Obj<T> {
      [key: string]: T;
    }
    let key: keyof Obj<number>; // keys的类型为number | string
    key = 123; // right
    //也可以使用访问操作符,获取索引签名的类型:
    
    interface Obj<T> {
      [key: string]: T;
    }
    const obj: Obj<number> = {
      age: 18
    };
    let value: Obj<number>["age"]; // value的类型是number,也就是name的属性值18的类型

    8、typescript里的get和set存取器(也可称魔术方法)

    let obj: {[key: string]: string} = {
        _name: 'aaa',
        set name (val: string) {
            console.log(val);
            this._name = val;
        },
        get name () {
            console.log('现在在取数');
            return this._name;
        }
    };
    
    console.log(obj.name);
    obj.name = 'are you ok???';
    console.log(obj.name);
    
    //get set 方法在类中的使用
    class Info {
        private _name: string;
        public constructor(name: string) {
            this._name = name;
        }
        public get name(): string{
            console.log('这个类里面的get方法');
            return this._name;
        }
        public set name(newValue: string) {
            console.log('这个是类里面的set方法');
            this._name = newValue;
        }
        public getName() {
            return this._name;
        }
    }
    
    let info = new Info('aaa');
    console.log(info.name);
    info.name = 'this is test';
    console.log(info.name);
    console.log(info.getName());

     9、typescript 中的类与接口的实现

    interface IClass {
        name: string;
        getName(): string;
    }
    
    class Info implements IClass {
        public name: string;
        public constructor(name: string) {
            this.name = name;
        }
        public getName(): string {
            return this.name;
        }
        public  setType<T>(type: T, times: number): T[] {
            console.log(this.name);
            return new Array(times).fill(type);
        }
    }

     10、模块的引入和输出 

    A、输出

    //模块的输出
    
    //变量的输出
    export let text: string = 'this is test';
    //对象的输出
    export let obj: {name: string, age: number} = {
        name: 'aaa',
        age: 20
    };
    //函数的输出
    export let func1 = (name: string, age: number): string => {
        return `${name}, ${age}`;
    };
    //输出一个集合
    let str = 'aaa';
    let obj1: {[name: string]: string | number} = {'token': 123456};
    let func2: (num: number) => void = (num: number): void => {
        console.log('ok');
    };
    export {
        str,
        obj1,
        func2
    }
    
    //输出一个类
    export class Test {
        public constructor() {
    
        }
    }
    
    //输出一个默认的内容可以用export default,但是一个类只能有一个export default
    //一般使用在一个文件只有一个类或者function的情况下
    export default class Check {
        public constructor() {}
    }

    如果引入npm包的时候的输出写法

    let str: string = 'this is test';
    export =  str;

    B、引入

    //引入全部模块,并起别名
    import * as All from './tools/model';
    //引入分块的模块
    import {func1 as t, func2, obj} from "./tools/model";
    //引入default模块
    import layer from './tools/model';
    //引入npm包,主要用自动化模块的引用
    import vue = require('vue');

     11、typescript的装饰器

    a、类的装饰器

    let state = function(target: any): void {       //只接收一个参数,这个参数就是所装饰的类
        target.prototype.say = function() {
            console.log('are you ok???');
        }
    };
    
    @state
    export default class Detail {
        private sign: boolean = false;
        public getSign(): boolean {
            return this.sign;
        }
    }
    
    let d = new Detail();    

    b、类里属性的装饰器

    let sign = function(target: any, key: string): void {    //具有两个属性,一个是类,一个是变量的名称
        Object.defineProperty(target, key, {
            get() {
                return 'are you ok???';
            }
        })
    };
    
    export default class Detail {
        @sign
        private state: string;
        public getInfo(): void {
            console.log(this.state);
        }
    }
    
    let d = new Detail();
    d.getInfo();        //输出are you ok???

    类里属性传参形式的装饰器

    let property = function(isChange: boolean = false): (target: any, key: string) => void {    //第一层外面传入的参数,第二层的参数和上面的参数一样
        return function(target, key) {
            Object.defineProperty(target, key, {
                get() {
                    return isChange? 'are you ok???': 'this is ok';
                }
            })
        }
    };
    
    export default class Detail {
        @property(true)
        private str: string;
        public getStr(): void {
            console.log(this.str);
        }
    }
    
    let d = new Detail();
    d.getStr();

    c、类里方法的装饰器

    let sign = function(target: any, key: string, obj: any): void {    //接收三个参数,第一个是类的本身,第二个是方法名,第三个defineProperty的第三个参数,可以对value进行处理
        let fn = obj.value;
        obj.value = function(...rest) {
            console.log('this is add');
            return fn.apply(target, rest);
        }
    };
    
    export default class Detail {
        @sign
        public getInfo(name: string): void {
            console.log(name, 'okok');
        }
    }
    
    let d = new Detail();
    console.log(d.getInfo('yf'));        //输出this is add, yf okok

     d、类里参数的装饰器

    let property = function(target: any, key: string, index: number){
        console.log(index);     //输出的是参数索引,如果修饰的是第一位参数则为0
    };
    
    export default class Detail {
        public getStr(@property name): void {
            console.log(name);
        }
    }
    
    let d = new Detail();
    d.getStr('test');
  • 相关阅读:
    golang中将json转成go
    软件升级
    golang 各类型转换
    golang 基础知识6
    golang 基础知识5
    bash resource
    toy
    links
    android abd remove
    YCM
  • 原文地址:https://www.cnblogs.com/rickyctbu/p/11180910.html
Copyright © 2011-2022 走看看