【TypeScript专栏】二、TypeScript基础(二)

59 阅读5分钟

2.7 Interface 接口

  • 对 对象的形状(shape)进行描述
  • Duck Typing(鸭子类型),是动态编程语言的一种对象推断的策略,它更关注对象如何被使用,而不是对象的类型本身。
  • Interface不会被转换js,只能用来做类型的静态检查
interface Person {
    name: string,
    age: number,
    sex?: string, // 可选属性,可不写 不会报错
    readonly id: number; // 只读属性,不可修改赋值
    // readonly 是用在属性上的关键字
}

// 由接口限制变量内的属性及个数 要求保持一致
let zhangsan: Person = {
    name: 'zhangsan',
    age: 20
}

// Cannot assign to 'id' because it is a read-only property.
zhangsan.id = 123; // 报错,不可更改只读属性

2.8 Function 函数

  • 在JS中,函数是一等公民。
    • 函数和其他类型的对象一样
      • 可以作为参数
      • 可以存入数组
      • 可以被另外一个函数返回
      • 可以被赋值给另外一个变量
  • 函数由两部分构成
    • 输入:通过不能数量的参数来实现
    • 输出:返回结果
// 参数后面写类型,为参数类型;
// 参数与花括号中间写类型,为返回值类型
// 可选参数,与对象类似,使用问号
// 但可选参数之后,不可添加确定的参数,否则对参数的类型判断会发生混乱,会报错
function add(x: number, y: number, z?: number): number {
    return x + y;
}

// 函数表达式 形式
// 当前add 本身也存在类型 函数类型
// 在ts中,凡是: 后面的都是在声明类型
const add: (x: number, y: number, z?: number): number => {
    return x + y;
}

// 声明与add 完全一样的类型
// 括号中带有参数的类型,与上方一致
// 此时的箭头不是ES6的箭头函数,而是ts中声明函数类型返回值的方法
// 在箭头之后,是返回值的类型
let add1: (x: number, y: number, z?: number) => number = add;

2.8.1 拓展

通过interface 构建函数的类型

// 这里的返回值类型不使用箭头,而是通过冒号
interface ISum {
   (x: number, y: number, z?: number): number 
}

2.9 类型推论、联合类型和类型断言

2.9.1 类型推论

当一个函数赋值给一个变量时,这个变量就获得了类型

let str = 'str';
str = 123; // 报错,当未给变量指定类型时,它会根据赋值自动推断出一个类型,与类型不符,则会报错

2.9.2 联合类型 union types

// 多个类型中使用竖线分割 |,被称为联合类型
let numberOrString: number | string
numberOrString = 123;
numberOrString = 'abc';

// 当TypeScript 不确定一个联合类型的变量,到底是什么类型时
// 只能访问此联合类型,所有类型里共有的属性/方法
numberOrString.length // 报错,非公有属性
numberOrString.toString() // 可用,属于共有方法

2.9.3 类型断言

告知编译器,这里的类型我很清楚,你要听我的,不应该再报错

  • 类型断言 通过 as 关键字
function getLenth(input: string | number): number {
    // as string,这时候input 就变为了一个string类型
    const str = input as string;
    if(str.length) {
        return str.length;
    } else {
        const number = input as number;
        return number.toString().length;
    }
}

// TypeScript的一个特性 type guard(守护)
// 当遇到一个联合类型时,使用条件语句,可以自动帮助缩小类型的范围
// 常用的关键字有 typeof instanceof
// instanceof 作用于类的实例
// 通过条件语句配合typeof 改写上述方法 实现相同效果
function getLenth(input: string | number): number {
    iftypeof input === 'string') {
        return input.length;
    } else {
        return input.toString().length;
    }
}

2.10 枚举 Enum

分为两种:常量值枚举和计算值枚举

  • 常量枚举
    • 值在编译时确定: 常量成员的值必须是字面量(数字、字符串)、其他常量成员的引用,或通过常量表达式计算的结果
    • 自动递增: 若未显式赋值,数字枚举的常量成员会从 0 开始自动递增(或基于前一个成员的值递增)。
    • 反向映射: 数字枚举的常量成员会生成反向映射(通过值获取键名)。
  • 计算值枚举
    • 值在运行时计算:成员的值通过函数调用、动态表达式或非字面量赋值。
    • 必须显式赋值:计算成员后的成员必须手动初始化(无法自动递增)。
    • 无反向映射:计算成员的值在编译时无法确定,因此不支持反向映射。
  • 只有常量值可以进行常量枚举

2.10.1 默认枚举

  • 枚举默认从 0 开始。
  • 枚举还做了反向映射,可以把枚举看成一个数组,使用相当于获取数组元素的方式,拿到对应索引下的元素。
enum Direction {
    Up,
    Down,
    Left,
    Right
}
console.log(Direction.Up); // 0
console.log(Direction[0]); // Up 

2.10.2 手动赋值枚举项

  • 手动赋值枚举项后,未赋值的枚举项,会接着递增
enum Direction {
    Up = 10,
    Down,
    Left,
    Right
}
console.log(Direction.Up); // 10
console.log(Direction.Down); // 11

2.10.3 字符串枚举

  • 若前面的 枚举项 加了字符串值,后面枚举项 也得是字符串,否则报错
enum Direction {
    Up = ‘UP',
    Down = 'DOWN',
    Left = 'LEFT,
    Right = 'RIGHT'
}
console.log(Direction.Up); // 'UP'
console.log(Direction.Down); // 'DOWN'

2.10.4 常量枚举

  • 在枚举前面加关键字 const 后,称之为常量枚举
  • 使用常量枚举,会提升性能,内联枚举的任何用法,并且不会把枚举编译成JavaScript代码
  • 转为js文件时,只会保留使用到的枚举值,且直接赋值保留
// 源ts文件
const enum Direction {
    Up = ‘UP',
    Down = 'DOWN',
    Left = 'LEFT,
    Right = 'RIGHT'
}
const value = 'UP';
if (value === Direction.Up) {
    console.log('go up')
}
// 转译后的js文件
var value = 'UP';
if (value === 'UP' /* Up */) {
    console.log('go up');
}