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{
    width: 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类一样的初始化过程

类型自动推断题目

const test  = {
  aa: {aaa: 1},
  bb: {bbb: 2}
}

type TestObj = typeof test;
const fun: <T extends keyof TestObj>(key: T) => TestObj[T] = key => test[key];
fun('aa');  // 自动推断为 {aaa: number}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,978评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,954评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,623评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,324评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,390评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,741评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,892评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,655评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,104评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,569评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,254评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,834评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,725评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,950评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,260评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,446评论 2 348

推荐阅读更多精彩内容