一文读懂typeScript的基础类型

113 阅读6分钟

什么是typescript

typeScriptjavascript的超集。遵循最新的ES5/ES6规范,Typscript扩展了javasrcipt的语法。

  • TS提供的类型系统,可以让我们在写代码的时候提供丰富的语法提示

  • 编译型语言,需要编译才能在浏览器运行

  • js可以开发大型的企业应用

  • 在编写代码的时候提供类型检查从而可以避免很多线上错误

基础语法

TS中,类型是在变量后面,以冒号隔开,类型需小写

    // 定义一个变量名称为name,变量的类型是string,值为bob,
    let name: string = 'bob'

变量在没有赋值前不允许直接使用:Variable 'name' is used before being assigned,所以我们在使用变量前,必须给变量赋值

    let name: string;
    // Variable 'name' is used before being assigned
    console.log(name);

基础类型

TS的基础类型共12种,包括js的5个基本类型:string, number, boolean , null 和undefind以及复杂类型array同时TS扩展定义的基础类型包括元组Tuple, 枚举, void, any, never

5个基本类型

    // 字符串
    let name: string = 'bob';
    
    // 数字
    let num: number = 123;
    
    // 布尔
    let statu: boolean = false;
    
    // undefined 只能赋值undefined
    let u: undefined = undefined;
    // undefined 可以赋值给void
    let str:void = undefined;
    
    // null 只能赋值null
    let n: null = null;

数组

在 TypeScript 中,数组类型有多种定义方式,比较灵活。

let arr:number[] = [1, 2, 3];

联合类型在数组中的使用

如果数组包含多种类型的话,那我们可以使用联合类型来定义数组

let arr:(number | string) = [1, 2, 3, 'abc'];

不能把多种类型的数组赋值给比它类型少的数组

let arr:(number | string)[] = [1, 2, 3, 'abc'];
let arr1:number[] = [1, 2, 3];
arr1 = arr;
// Type '(string | number)[]' is not assignable to type 'number[]

元组

元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同但是赋值时必须是与所定义的类型一致的

基本使用

    // 定义一个包含`string`和`number`的数组
    let arr:[string, number] = ['aa', 123];
    
    // 打乱类型的顺序赋值
    arr = [123, 'aa'];  // Error
    
    // 赋值其他类型
    arr = ['aa', true]   // Error
    
    // 数组的元素大于定义的长度,或者小于定义的长度
    arr = ['aa', 123, 123]  // Error
    arr = ['aa']  // Error

越界添加

    let arr:[string, number] = ['aa', 123];
    // 越界添加时,它的类型会被限制为元组中每个类型的联合类型
    arr.push(111);
    // 虽然可以通过push方法添加,但是不可以越界访问
    console.log(arr[2]) // Error
    // 但是可以通过下面的方式读取,但是不建议这样使用
    console.log(arr[arr.length - 1])
    arr.push(true) // Error
    // 不可以通过索引越界添加
    arr[2] = 'ccc' // Error

枚举

enum类型是对JavaScript标准数据类型的一个补充,可以为一组数值赋予友好的名字。

  • 枚举是只读的,不能修改
  • 默认从0开始为元素编号,也可以手动指定成员的值
  • 如果前一个元素的值非数字,当前元素的值需要手动指定,不建议这样使用,通常一组枚举数据的类型应该是一致的
  • 如果枚举元素是数字,可以根据枚举的值找到它的名字
    // 手动指定前一个元素,后面依次累加
    enum Color {Red = 1, Green, Blue};
    let c: Color = Color.Green; // 2
    
    // 不指定,默认从0开始
    enum Color {Red, Green, Blue};
    let c: Color = Color.Green; // 1
    
    // 指定一个元素为字符串,后面不赋值的话,报错
    enum Color {Red = 'red', Green, Blue};
    let c: Color = Color.Green; // Error
    
    // 修改元素的值,报错
    enum Color {Red, Green, Blue};
    Color.Red = 3; // Error
    
    // 如果枚举元素是数字,可以根据值找到它的名字
    enum Color {Red, Green, Blue};
    console.log(Color[1]) // Green

常数枚举

常数枚举是使用 const enum 定义的枚举类型:

const enum Directions {
    Up,
    Down,
    Left,
    Right
}

let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right];

常数枚举与普通枚举的区别是,它会在编译阶段被删除,并且不能包含计算成员。

上例的编译结果是:

var directions = [0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right */];

所以常量枚举不能直接打印directions

console.log(directions);
// const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query

假如包含了计算成员,则会在编译阶段报错:

const enum Color {Red, Green, Blue = "blue".length};

// const enum member initializers can only contain literal values and other computed enum values

any

任意类型,也就是我们不限制变量的类型,这样类型检查器就不会对它做检查。此时更接近于js,可以给它赋值任意类型的数据而不影响使用
通常我们在编程阶段,或者是使用其他第三方类库时候,或者是由后台传递的数据在不清楚类型的情况下给它赋值any。

    let notSure: any = 4;
    notSure = "aaa";
    notSure = false;

任意类型可以访问任意属性和方法,也可以正常编译,也可以正常访问,但如果属性和方法是不存在的,在代码执行节点会报错。

    let notSure: any = 4;
    console.log(notSure.aaa) // 执行时候报 Error
    notSure.getName()  // 执行时报 Error

变量在定义时没有指定任何类型,那么它会被指定为任意类型

    let notSure;
    notSure = 4;
    notSure = false;

注意在定义时赋默认值的时候,会按照类型推论的规则推断出一个类型

    // 推断出类型为string
    let notSure = 'aa';
    notSure = 4;    // 报错
    notSure = false; // 报错

void

没有任何类型或者是不关心返回值。当一个函数没有返回值时,你通常会见到其返回值类型是 void

    function warnUser(): void {
        console.log("This is my warning message");
    }

声明一个void类型的变量没有什么大用,因为你只能为它赋予undefinednull

    let unusable: void = undefined;

never

never类型表示的是那些永不存在的值的类型。 例如, never类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型; 变量也可能是 never类型,当它们被永不为真的类型保护所约束时。

never类型是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是never的子类型或可以赋值给never类型(除了never本身之外)。 即使 any也不可以赋值给never

    // 返回never的函数必须存在无法达到的终点
    function error(message: string): never {
        throw new Error(message);
    }

    // 推断的返回值类型为never
    function fail() {
        return error("Something failed");
    }

    // 返回never的函数必须存在无法达到的终点
    function infiniteLoop(): never {
        while (true) <img src="{" alt="" width="30%" />
        }
    }