原始类型


Javascript原始类型也同样适用于 TypeScript的类型系统。因此,string, number,boolean也可以被用作类型注解:

  1. let num: number;
  2. let str: string;
  3. let bool: boolean;
  4. num = 123;
  5. num = 123.45;
  6. num = '123'; //Type '"123"' is not assignable to type 'number'
  7. str = '123';
  8. str = 123; //Type '123' is not assignable to type 'string'
  9. bool = true;
  10. bool = false;
  11. bool = 'false';//Type '"false"' is not assignable to type 'boolean'.

数组

类型注解+[],它能让你安全的使用任何有关数组的操作,而且它能放置一些类似赋值错误类型给成员的行为。

  1. // 元素类型加[]写法
  2. let list:number[] = [1,2,3]
  3. // 数组泛型写法
  4. let list: Array<number> = [1,2,3]

元祖

已知元素数量类型的数组

  1. // 声明一个元组类型
  2. let x: [string, number];
  3. // 初始化赋值
  4. x = ['hello', 10]; // OK
  5. // 初始化错误
  6. x = [10, 'hello']; // Error

枚举

在计算机语言中一般用数值来表示某种状态,这种方式不直观,可读性很差。枚举就是把给一些计算机的状态(数字)和一个自然语言相应含义的单词对应起来,目的是把所有的情况都用枚举写出来,这样根据不同的状态对应不同的枚举值,提高了代码的可读性。

枚举类型可以为一组数值赋予友好的名字。默认情况下,从0开始为元素编号,你也可以手动的指定成员的编号。

  1. enum Color {Red = 1,Geeen = 2, Blue = 4}
  2. let c: Color = Color.Green

编译后

  1. var Color;
  2. (function (Color) {
  3. Color[Color["Red"] = 1] = "Red";
  4. Color[Color["Green"] = 2] = "Green";
  5. Color[Color["Blue"] = 4] = "Blue";
  6. })(Color || (Color = {}));
  7. console.log(Color) // 在函数最后进行打印,返回一个JSON
  8. var c = Color.Green;

枚举的名对应是一个变量,然后判断是否有值,如果没有赋值json,然后在自调用函数里,对对象进行赋值,可以在函数最后进行打印,此时json里的值所有的表达式都有返回值,它的返回值就是等号右边的赋值。

  1. { '1': 'Red', '2': 'Green', '3': 'Blue', Red: 1, Green: 2, Blue: 3 }

如果你看不大明白上面的代码,那么你必须知道console.log(Color["Red"]=0)返回0。

此外,枚举类型提供的一个遍历是你可以由枚举的值得到它的名字(从上面编译后的源码就可以看出)。例如,我们知道值为2,但是不确定它映射到Color里的哪个名字,我们可以查找相应的名字:

  1. enum Color {Red = 1, Green, Blue}
  2. let colorName: string = Color[2];
  3. console.log(colorName); // 显示'Green'因为上面代码里它的值是2

null & undefined

null和undefined是其他所有类型的子类型

  1. const n1:null = 123;
  2. const n2:undefined = '123';

如果一个变量的值确实需要是null或者undefined, 可以像下面这么用, ts会自动根据if/else推导出正确类型:

  1. // 这是"联合类型", 在"高级类型"中会有详细介绍, 表示n可能是undefined也可能是number
  2. let num: undefined|number;
  3. if(Math.random()>0.5) num = 1;
  4. if(undefined !== num) {
  5. num++;
  6. }

any

any类型在 TypeScript 类型系统中占有特殊的地位。它提供给你一个类型系统的【后门】,TypeScript将会把类型检查关闭。在类型系统里any能够兼容所有的类型(包括它自己)。因此,所有的类型都能够被赋值给它。它也能被赋值给其他任何类型。

void

使用 :void来表示一个函数没有返回值

  1. function log(message:string):void{
  2. console.log(message)
  3. }

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

  1. let unusable:void = undefined

never

never表示不可达, 用文字还真不好描述, 主要使用在throw的情况下:

  1. function error():never{
  2. throw '错了!';
  3. }

进阶

interface

订立接口有助于我们对对象内的值进行更好的进行类型标注。但是接口只能规范属性和值的类型。另外,接口中定义的属性就是必须存在的属性。当然,你也可以在属性后面紧跟可选符号?,来表示某个属性是非必须的。

如果我们用对象的格式存储出行需要的装备,那么可以定义Trip的类型为:

  1. interface Trip {
  2. bag: number;
  3. kettle: number;
  4. map: boolean;
  5. compass: boolean;
  6. destination: string;
  7. magazine?: boolean;
  8. biscuit: boolean;
  9. }
  10. function checkEquipment(ready: Trip): void {
  11. let ct: string[] = []
  12. for (let i in ready) {
  13. ct.push(i)
  14. }
  15. console.log(`这次出行,我们带上的装备有: ${ct.join('、')}`)
  16. }
  17. const ready = {bag: 3,kettle: 3,map: true, compass: true,destination: 'AMAZON',biscuit: true}
  18. checkEquipment(ready)

在这种情况下,当我们给ready赋值的时候, 如果任何一个字段没有被赋值或者字段对应的数据类型不对, ts都会提示错误, 这样就保证了我们写代码不会出现上述的小错误。

可选选项(?)

上面的例子中,出门远行不一定要带magazine,该字段可以不用传值。但是不传的化又会报错!这时候就需要标记magazine字段为可选选项。同样,函数的参数也可以是可选的。

只读属性(readonly)

接口的只读属性可以在前面添加readonly关键字,来指定这个属性在初始化后就无法被改变,否则报错,如下

  1. // 只读属性
  2. interface Point {
  3. readonly x: number;
  4. readonly y: number;
  5. }
  6. let p1: Point = {x: 5, y: 10}
  7. p1.x = 10
  8. // Cannot assign to 'x' because it is a read-only property.ts(2540)

此外,ts默认有ReadonlyArray<T>类型,确保数组被创建后无法被任何方法和途径修改,甚至包括把它赋值给一个普通数组。如果要赋值给另一个数组,必须使用as类型断言。

  1. let a: number[] = [1, 2, 3, 4];
  2. let ro: ReadonlyArray<number> = a;
  3. ro[0] = 12; // error!
  4. ro.push(5); // error!
  5. ro.length = 100; // error!
  6. a = ro; // error!
  7. // 使用断言
  8. a = ro as number[];