Typescript-入门

82 阅读6分钟

一、开发准备

     1.npm install -g typescript

     2. tsc filename.ts  //编译成js文件

vscode开发环境集成:

    1.tsc --init 修改自定义配置
    
    2.terminal ->run task :选择tsc:watch - tsconfig.json

二、数据类型:

     1.布尔值:

    let isOk: boolean = false;

     2.数字类型:number,支持10,16,2,8进制的数字类型:

        let dec=100;

        let hex= 0x32;

        let bina=0b11;

        let octal=0o77;

    3.字符串:

        let name:string = 'typescript';

        let str:string=`welcome to learn ${name}`

    4.数组:

    let list: number[]=[1,2,3]
    or 
    let list:Array<number>=[1,2,3]

    5.元组(tuple):已知元素数量和类型的数组,数组的一种:各元素的类型不必相同,对应位置的类型需要相同;

 let x:[string,number] = ['a',1]

    6.枚举:用于定义数值集合;

       enum Color {Red,Green,Blue}  //先定义类型

       let c:Color = Color.Green;    value?

 编译

    let Color;

    (function (Color) {
        Color[Color["Red"] = 0] = "Red";
        Color[Color["Green"] = 1] = "Green";
        Color[Color["Blue"] = 2] = "Blue";
    })(Color || (Color = {}));
    
    let c = Color.Green; //1

    默认从0开始编号,可以手动赋值:
    enum Color {Red=2,Green,Blue}  
    let c = Color.Green; //3

7.Any:在编码阶段确实不能确定类型时使用;此时不会进行类型检查;

  let anyone:any=1;

  anyone='some'

  anyone=true

8.void:和any相反,没有类型;

    function no:void(){}

9.null、undefined

10.never:表示永不存在的值的类型;这意味着声明为 never 类型的变量只能被 never 类型所赋值,在函数中它通常表现为抛出异常或无法执行到终止点(例如无限循环)

    let x: never;

    // 运行错误,数字类型不能转为 never 类型`
    x = 123;

    // 运行正确,never 类型可以赋值给 never类型
    x = (()=>throw new Error('exception')})();

11. 类型断言: 类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构。 它没有运行时的影响,只是在编译阶段起作用。

    类型断言有两种形式。 其一是“尖括号”语法:

    let someValue: any = "this is a string";

    let strLength: number = (<string>someValue).length;

   另一个为as语法:

  let strLength: number = (someValue as string).length;

 

三、变量声明

数据声明格式:

    var/let/const  [变量名] : [类型] = 值;

js中的声明都可以使用;

注意一下解构类型的声明:

    let o = { a"foo", b12, c"bar" };

    let {a, b}: {a: string, b: number} = o;

四、函数定义

    function add(x: number, y: number): number {

       return x + y;

    }

我们可以给每个参数添加类型之后再为函数本身添加返回值类型。 TypeScript能够根据返回语句自动推断出返回值类型,因此我们通常省略它。

函数重载

重载是方法名字相同,而参数不同,返回类型可以相同也可以不同。

每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

参数类型不同:
    function disp(x:string):void;
    function disp(x:number):void;

参数数量不同:
    function disp(x:string):void;
    function disp(x:string,y:number):void;

参数类型顺序不同:
    function disp(x:number,y:string):void;
    function disp(x:string,y:number):void;
    
例:
    function disp(n1:number,s1:string):void;
    function disp(n1:number,s1:number):number;

    function disp(x:any,y:any):any{
        console.log(x+y)
        return x+y 
    } 

    disp(1,"abc")
    disp(1,2);

五、接口

接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法\

    interface LabelledValue { label:string;}
    
    function printLabel(labelledObj: LabelledValue) {
        console.log(labelledObj.label);
    }
    
    printLabel({label: "Size 10 Object" });
    printLabel({label: 123}); //error

image.png

可选属性

接口里的属性不全都是必需的。 有些是只在某些条件下存在,或者根本不存在;

带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个?符号。

    interface Square { color?: string; width?: number; }

    function createSquare(config: Square): {color: string; area: number}{
        let newSquare = {color: "white" , area: 100 };
        
        if (config.color) {
            newSquare.color = config.color;
        }
        
        if (config.width) {
            newSquare.area = config.width * config.width;
        }
        
        return newSquare;
    }

    let mySquare = createSquare({color: "black" });
    let s1 = createSquare({width: 100 });

只读属性

一些对象属性只能在对象刚刚创建的时候修改其值。 你可以在属性名前用 readonly来指定只读属性:

    interface Point { readonly x: number; readonly y: number; }

    let p1: Point = { x10, y20 };

    p1.x5// error!

TypeScript具有ReadonlyArray<T>类型,它与Array<T>相似,只是把所有可变方法去掉了,因此可以确保数组创建后再也不能被修改:

    let a: number[] = [1234];

    let ro: ReadonlyArray<number> = a;

    ro[0] = 12// Index signature in type 'readonly number[]' only permits reading.

    ro.push(5); // Property 'push' does not exist on type 'readonly number[]'.

    ro.length100//Cannot assign to 'length' because it is a read-only property.

    a = ro; // The type 'readonly number[]' is 'readonly' and cannot be assigned to the mutable type 'number[]'.

函数类型

接口能够描述JavaScript中对象拥有的各种各样的外形。 除了描述带有属性的普通对象外,接口也可以描述函数类型。

为了使用接口表示函数类型,我们需要给接口定义一个调用签名。 它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型。

    interface SearchFunc { (source: string, subString: string): boolean ; }
    let mySearch: SearchFunc = function(source: string, subString: string) {
        let result = source.search(subString);
        return result > -1;
    }
    
    //对于函数类型的类型检查来说,函数的参数名不需要与接口里定义的名字相匹配。 比如,我们使用下面的代码重写上面的例子:
    let mySearch: SearchFunc = function(src: string, sub: string): boolean {
        let result = src.search(sub);
        return result > -1;
    }

可索引的类型

能够通过索引得到的类型

interface StringArray { [index: number]: string; }
let myArray: StringArray;
myArray = [ "Bob", "Fred" ];

let myStr: string = myArray[ 0 ];
myArray = [ 1, 2 ];//Type 'number' is not assignable to type 'string'

-----------------------------

interface StringArray { [index: string]: string; }
let myArray: StringArray;
myArray = {a: '1' };

let myStr: string = myArray['0']; //不会报错

TypeScript支持两种索引签名:字符串和数字。 可以同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值类型的子类型。

这是因为当使用 number来索引时,JavaScript会将它转换成string然后再去索引对象。

也就是说用 100(一个number)去索引等同于使用"100"(一个string)去索引,因此两者需要保持一致。

类类型

实现接口

与C#或Java里接口的基本作用一样。

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 PenStroke { penWidth: number; }
    interface Square extends Shape, PenStroke { sideLength: number; }
    
    let square = <Square>{}; 
    square.color = "blue";
    square.sideLength = 10;
    square.penWidth = 5.0;

 六: 类

    class Greeter { 
        greeting: string;
        constructor(message: string) {
            this.greeting = message;
        }
        greet():string {
            return "Hello, "this.greeting;
        }
    }

    let greeter = new Greeter( "world" );

继承:

需要注意的是子类只能继承一个父类,TypeScript 不支持继承多个类,但支持多重继承,如下实例:

    class Root { str:string; }
    class Child extends Root {}
    class Leaf extends Child {} // 多重继承,继承了 Child 和 Root 类
    
    var obj = new Leaf();
    obj.str = "hello"
    console.log(obj.str)