typescript 学习笔记

typescript

编译命令

  • tsc app.ts

基本数据类型

- var isBoon:boolean = false; (不给值默认 undefined)

- var num: number = 10;

- var str: string = "abc";  

- var list1: number[] = [1,2,3];   (方式1)

- var list2: Array<string> = ["a","b"];  (方式2)

- 枚举类型 enum Color {red,green,blue};

- 任何类型 var notSure: any = 10;

- void类型(函数)
// 枚举  (一个星期)

enum Color {red,green,blue};
var colorName: string =  Color[1];    // green

// 可自己更换下标
enum Color {red = 10,green = 20,blue};
var colorName: string =  Color[10];    // red

// 获取下标
var c: Color = Color.green;
console.log(c)     // => 20
// any 类型   可改变其值

var notSure: any = 10;
notSure =  "hello";
notSure = false;

console.log(notSure)    // false;

var list: any[] = [1,"hehe",false];
console.log(list[1])   // hehe
// void 类型   函数
function demo1(): string {}   // 返回值类型 string
function dmeo2(): number{}  // 返回值类型 number
function demo3():  void{}  // 此函数可以有返回值也可以没有

函数类型

// 命名函数
// 可指定形参可返回值的类型
function add(x: number, y: number): number{
    return x+y
} 

// 匿名函数
var myAdd = function (x: number, y: string): string{
    return "hello TS"
}

// 让参数有明确的意义
var myAddts: (name: string, age: number) => number = function(n: string, a: number): number {
    return a;
}

// =================================================

// 可选参数
function buildName(firstName: string, lastName: string) {
    return firstName + lastName;
}
var result = buildName("hhe","haha");
var result2 = buildName("hehe");  // 报错  少一个参数
var result = buildNmae("hehe", 'haha', 'dudu'); // 报错 超出参数

// ? 表示可传可不传
function buildName(firstName: string, lastName?: string){
    if(lastName){
        return firstName + lastName;
    }else{
        return firstName;
    }
}
var result = buildName("hhe", "haha");
var result2 = buildName("hehe");  // 正常编译
var result3 = buildNmae("hehe", 'haha', 'dudu'); // 报错 超出参数

// =================================================

// 默认参数
function buildName(firstName: string, lastName: string = "liu"){
    return firstName + lastName;
}
var result = buildName("liu");  // liuliu
var result2 = buildName("liu",'xin');  // liuxin
var result3 = buildName("liu","xin","ya");  // error

// =================================================
// 可变参数(不限参数的个数)
function demo(firstName: string, ...restOfname: string[]){
    return firstName + "" + restOfname.join(" ")
}
var a = demo("a",'b','c','d');

Lambads和this关键字的使用

var people = {
    name:['a','b','c'],
    getName: () => {
        var i = Math.floor(Math.random()*4);
        return {
            n: this.name[i]
        }
    }
}
var myName = people.getName();
alert(myName().n) 

重载

function attr(name: string): string;
function attr(age: number): number;
function attr(nameorage: any): any{
    if(nameorage && typeof nameorage === 'string'){
        alert("姓名")
    }else{
        alert("年龄")
    }
}
attr('hello');   // 姓名
attr(10);   // 年龄

class Person {
    name: string;
    age: number;
    constructor(name: string,age: number){
        this.name = name;
        this.age = age;
    }
    print(){
        return this.name + this.age
    }
}
var p = new Person("hehe", 18);  // 必须传参
p.print();

类的继承

class Person {
    name: string;
    age: number;
    tell() {
        return this.name + ":" + this.age;
    }
}

// 表示学生类也拥有Person类的name和age属性
class Student extends Person {
    school: string;
    tell() {
        return this.name + this.age + this.school
    }
}
var s = new Student();
s.name = "liu";
s.age = 800;
s.school = "hehe";
alert(s.tell());

//  ========================

class Person {
    name: string;
    age: number;
    constructor(name: string,age: number){
        this.name = name;
        this.age = age;
    }
    tell(){
        return this.name + ":" + this.age;
    }
}

class Student extends Person {
    school: string;
    constructor(school: string){
        this.school = school;
        super("liu", 20);
    }
    tell(){
        return this.name + this.age + this.school
    }
}
var s = new Student("hehe");
alert(s.tell());   // liu20hehe

访问修饰符

  • public 默认
  • private
class Person {
    private name: string;   // 表示私有属性 不可被继承
    age: number;
    print(){
        return this.name + this.age
    }
}
class Stu extends Person{
    school: string;
    print() {
        return this.name + this.age + this.school
    }
}
var stu1 = new Stu();
stu1.name = "liu";
stu1.age = 18;
stu1.print();
// 这样编译会报错   应为Person类的name是私有属性,stu访问不到

// ==============

class Person {
    name: string;
    age: number;
    constructor(private name: string, age: number){
        this.name = name;
        this.age = age;
    }
    print(){
        return this.name + this.age;
    }
}
class Stu extends Person {
    school: string;
    constructor(school) {
        this.school = school;
        super("liu", 18)
    }
    print(){
        return this.name + this.age + this.school;
    }
}
var stu1 = new Stu("hehe");
stu1.print();   // 报错 因为Person的name是私有的

封装的实现

class Person {
    private name: string;
    say() {
        return this.name;
    }
}
var p = new Person();
p.name = "liu";
p.say();  // 报错

// 访问和设置私有属性

class Person {
    private name: string;
    say(){
        return this.name
    }
    get _name(): string{
        return this.name;
    }
    set _name(newName: string){
        this.name = newName;
    }
}
var p = new Person();
p._name = "haha";
alert(p.say())  // haha

static 的使用

class Person {
    static name: string ;
    tell() {
        return this.name
    };
}
var p = new Person ();
p.name = "liu";   // 报错  static不能通过实例对象来调用
p.tell();

// =======正确调用name属性====
class Person {
    static name: string;
    tell(){
        return Person.name;   // 类名.属性名
    }
}
var p = new Person(); // 类名.属性名
Person.name = "liu";
p.tell();

接口

function fn(obj: {name: string}){
    alert(obj.name);
}
var myObj = {name: "liu"};
fn(myObj)

// ===================
interface labelValue{
    name: string;
}
function print(label: labelValue){
    alert(label.name)
}
var obj = {name: "xin"};
print(obj)

接口的可选属性

interface USB{
    name:string;
    age:number;
}
function print(obj: USB){
    console.log(obj.name)
    console.log(obj.age)
}
var obj = {name: "liu", age: 10};
print(obj)
// obj里面必须有name和age

// =================
interface USB{
    name?: string;
    age?: number;
}
function print(obj: USB){
    console.log(obj.name)
    console.log(obj.age)
}
var obj = {name: "liu"};
print(obj)
// ? 代表可选  name和age都可以不写

接口的函数类型

interface PersonFun {
    (name: string,age: number): boolean
}
var fn : PersonFun;
fn = function(name: string,age: number){
    return false;
}

接口的数组类型

interface StringArray{
    [index:number]: string;
}
var myArr: StringArray;
myArr=["a","b",'c']

接口的class类型

interface ClockInterface {
    currentTime: Date;
    setTime(d: Date);
}
class Clock implements ClockInterface{
    currentTime: Date;
    setTime(d: date){
        this.currentTime = d;
    }
    constructor(h: number, m: number){

    }
}

接口继承与混合类型

interface Shape{
    color: string;
}
interface Square extends Shape{
    sideLength: number;
}
var s = <Square>{};
s.color = "blue";
s.sideLength = 10;

// 多继承
interface Shape{
    color: string;
}
interface Stroke{
     number;
}
interface Square extends Shape,Stroke{
    sideLength: number;
}
var s = <Square>{};
s.color = 'blue';
s.width = 10;
s.sideLength = 10;

// 混合类型
interface hehe {
    name: string;
    fn(): void;
    (age: number): string;
}
var c: hehe;
c(10);.
c.fn();

接口其他

// 有时候定义一个接口,里面的属性个数是不确定的
interface A {
  name: string;
  age: number;
  family: Array<string>;
  say: () => {};
  [prop: string]: any;  // 就是这个东西
}

//  往TreeDataObject中再添加另外两个新属性 & 符号
resultData: (TreeDataObject & {
        title: string;
        origin?: TreeDataObject
    })[] = []

泛型

  • 有时候在定义变量的时候不确定变量的类型
function Hello<T>(arg: T): T{
    return arg;
}
var output = hello<string>("hello");
alert(output)

泛型的基本应用

function Hello<T>(num: T): T{
    alert(str.length);   // 报错  没有自定泛型的类型 没有length
    return num;
}
// ==============================
function Hello<T>(str: T[]): T[]{
    alert(str.length);
    return str;
}
var list:Array<string> = hello<string>(['a','b','c'])

模块

var myModule = function(vip){
    // 声明私有成员
    var Yvip = document.getElementById(vip);
    return {
        // 公开成员
        add: function(t){
            Yvip.innerHTML = "呵呵";
        }
    }
}

// =====================

module Time{
    export class Test{
        element: HTMLElement;
        span: HTMLElement;
        timer: number;
        constructor(e: HTMLElement){
            this.element = e;
            this.element.innerHTML = "现在时间是:";
            this.span = document.createElement("span");
            this.element.appendChild(this.span);
            this.span.innerHTML = new Date().toTimeString();
        }
        start(){
            this.timer = setInterval(()=>{this.span.innerHTML = new Date().toTimeString()},500)
        }
        stop(){
            clearInterval(this.timer);
        }
    }
}

模块之间的引用

  • 三斜杠表达式
/// <reference path="./Validate" />

// 表示引入了一个同级文件夹下的Validate模块
// 引入后可用 Validate模块里面暴露出来的方法和属性

装饰器

// target 作用目标 Perple类 Object
// key  具体作用对象  'say' string
// desc 元数据描述  Objects
function test(target: any, key: string, desc: PropertyDescriptor) {
    console.log(target, key, desc)
    let method = desc.value;
    desc.value = function (flag:  boolean) { 
        if (flag) {
            console.log('要打印了')
        } else {
            method()
        }
    }     
}
class People {
    name: string;
    constructor(name) {
        this.name = name;
    }
    @test
    say(flag: boolean) { 
        console.log('是否打印')
    }
}
let p = new People('liu');
p.say(true)
p.say(false)

// 装饰器工厂
function test(arg) {
  return function(target, key, desc) {}
}
// 这种方式可以自己再传参(arg)

关于 reflect-metadata

  • 它可通过反射机制, 获取参数类型列表

  • 类型元数据使用元数据键"design:type"

  • 参数类型元数据使用元数据键"design:paramtypes"

  • 返回值类型元数据使用元数据键"design:returntype"

  • 实现的依赖注入

import 'reflect-metadata';
let targetLists: Map<any, any[]> = new Map();   //  @Injectable 装饰器作用的所有目标列表
let instanceLists: Map<any, any> = new Map(); // 实例列表
export function Injectable(_constructor: Function) {
    // 通过反射机制,获取参数类型列表    
    let paramsTypes: Array<Function> = Reflect.getMetadata('design:paramtypes', _constructor);
    targetLists.set(_constructor, paramsTypes);
}
// 这个实例用来获取依赖注入的实例
export function Ioc(injet: any){
    return getIocInstance(injet);
}
function getIocInstance(inject: any) {
    // 存在这个实例
    if(instanceLists.has(inject)) {
        return instanceLists.get(inject);
    } else {
        // 不存在
        let relies = targetLists.get(inject) || [];
        let instance = new inject(...relies.map((rely) => {
            return getIocInstance(rely);
        }));
        instanceLists.set(inject, instance);
        return instance;
    }
}

@Injectable
export class Person {
    constructor(
        net: Unetservice,
    ) {}
    speak() {
        this.net........
    }
}
let p: Person = Ioc(Person);
  • @Injectable 把 Person类已经存到 targetLists 里了
  • Ioc 是 先看一下 instanceLists 里面有没有 Peroson的实例, 有的话 直接拿出来
    没有的话 实例化,并存到 instanceLists (方便下次ioc 直接从 instanceLists拿) 再拿出来
  • 每一个类再实例化的时候, 它的constructor里面的依赖参数类 也会有和Person类一样的初始化过程


作者:liuxinya
链接:https://www.jianshu.com/p/be615c82c8a2
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
原文地址:https://www.cnblogs.com/telwanggs/p/10954081.html