even

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

在用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();
const propDec = <T>(classT: T, prop: string|symbol) => {
    let temp: any;
    Object.defineProperty(classT, prop, {
        get() {
            return temp
        },
        set(val) {
            temp = val + 'yes'
        }
    })
}

class Test {

    @propDec
    private state: string

    public check(): void {
        this.state = 'test'
        console.log(this.state)
        this.state = 'abc'
        console.log(this.state)
    }
}

new Test().check()

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');

 

posted on 2019-07-13 15:51  even_blogs  阅读(374)  评论(0编辑  收藏  举报