typescript 學(xué)習(xí)筆記

typescript

編譯命令

  • tsc app.ts

基本數(shù)據(jù)類型

- var isBoon:boolean = false; (不給值默認(rèn) 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類型(函數(shù))
// 枚舉  (一個星期)

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

// 可自己更換下標(biāo)
enum Color {red = 10,green = 20,blue};
var colorName: string =  Color[10];    // red

// 獲取下標(biāo)
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 類型   函數(shù)
function demo1(): string {}   // 返回值類型 string
function dmeo2(): number{}  // 返回值類型 number
function demo3():  void{}  // 此函數(shù)可以有返回值也可以沒有

函數(shù)類型

// 命名函數(shù)
// 可指定形參可返回值的類型
function add(x: number, y: number): number{
    return x+y
} 

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

// 讓參數(shù)有明確的意義
var myAddts: (name: string, age: number) => number = function(n: string, a: number): number {
    return a;
}

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

// 可選參數(shù)
function buildName(firstName: string, lastName: string) {
    return firstName + lastName;
}
var result = buildName("hhe","haha");
var result2 = buildName("hehe");  // 報錯  少一個參數(shù)
var result = buildNmae("hehe", 'haha', 'dudu'); // 報錯 超出參數(shù)

// ? 表示可傳可不傳
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'); // 報錯 超出參數(shù)

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

// 默認(rèn)參數(shù)
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

// =================================================
// 可變參數(shù)(不限參數(shù)的個數(shù))
function demo(firstName: string, ...restOfname: string[]){
    return firstName + "" + restOfname.join(" ")
}
var a = demo("a",'b','c','d');

Lambads和this關(guān)鍵字的使用

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;
    }
}

// 表示學(xué)生類也擁有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 默認(rèn)
  • 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();
// 這樣編譯會報錯   應(yīng)為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是私有的

封裝的實現(xiàn)

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

// 訪問和設(shè)置私有屬性

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不能通過實例對象來調(diào)用
p.tell();

// =======正確調(diào)用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都可以不寫

接口的函數(shù)類型

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

接口的數(shù)組類型

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

接口其他

// 有時候定義一個接口,里面的屬性個數(shù)是不確定的
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)

泛型的基本應(yīng)用

function Hello<T>(num: T): T{
    alert(str.length);   // 報錯  沒有自定泛型的類型 沒有l(wèi)ength
    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 = "現(xiàn)在時間是:";
            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 作用目標(biāo) Perple類 Object
// key  具體作用對象  'say' string
// desc 元數(shù)據(jù)描述  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)

關(guān)于 reflect-metadata

  • 它可通過反射機制, 獲取參數(shù)類型列表

  • 類型元數(shù)據(jù)使用元數(shù)據(jù)鍵"design:type"

  • 參數(shù)類型元數(shù)據(jù)使用元數(shù)據(jù)鍵"design:paramtypes"

  • 返回值類型元數(shù)據(jù)使用元數(shù)據(jù)鍵"design:returntype"

  • 實現(xiàn)的依賴注入

import 'reflect-metadata';
let targetLists: Map<any, any[]> = new Map();   //  @Injectable 裝飾器作用的所有目標(biāo)列表
let instanceLists: Map<any, any> = new Map(); // 實例列表
export function Injectable(_constructor: Function) {
    // 通過反射機制,獲取參數(shù)類型列表    
    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類已經(jīng)存到 targetLists 里了
  • Ioc 是 先看一下 instanceLists 里面有沒有 Peroson的實例, 有的話 直接拿出來
    沒有的話 實例化,并存到 instanceLists (方便下次ioc 直接從 instanceLists拿) 再拿出來
  • 每一個類再實例化的時候, 它的constructor里面的依賴參數(shù)類 也會有和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}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容