初识TypeScript | 青训营笔记

50 阅读4分钟

这是我参与「第四届青训营」笔记创作活动的的第 16 天。

什么是TypeScript?

TypeScript微软开发的一门编程语言,通过在JavaScript的基础上添加静态类型定义构建而成,可以编译成纯 JavaScript,并且支持ES6标准,提供了基于类的面向对象编程的模式。你可以把它理解为JavaScript的超集。

基础类型

Boolean 类型

const bool: boolean = true;

Number 类型

const num: number = 6;

String 类型

const str: string = "str"

Enum 枚举类型

枚举类型通常用于定义数值集合。使用枚举可以定义一些带名字的常量,可以清晰地表达意图或创建一组有区别的用例。TS支持基于数字的和基于字符串的枚举。

数字枚举

enum Direction{
    UP,
    DOWN,
    LEFT,
    RIGHT
}

const up: Direction = Direction.UP
console.log(up) // 0

设置初始值 - 自增长

enum Direction{
    UP = 5,
    DOWN,
    LEFT,
    RIGHT
}

const up: Direction = Direction.UP
const down: Direction = Direction.DOWN
console.log(up) // 5
console.log(down) // 6

字符串枚举

enum Direction { 
    UP = "上", 
    DOWN = "下", 
    LEFT = "左", 
    RIGHT = "右"
}
const up: Direction = Direction.UP
console.log(up) // 上

常量枚举

使用const关键字修饰的枚举不同于普通的枚举,它在编译阶段会被删除。

普通的枚举: image.png

常量枚举: image.png

Array 数组类型

定义数组的两种方式:

const arr1: number[] = [1,2,3]
const arr2: Array<number> = [4,5,6]

Tuple 元组类型

元组类型允许表示一个已知元素数量和类型数组,各元素的类型不必相同。
例如:可以定义一对值分别为stringnumber类型的元组。
在赋值时,元素的类型和位置都不能写错,且长度等于定义元组时的长度。

let x: [string, number]; 
x = ['hello', 10]; // OK
x = [10, 'hello']; // Error
x = ['hello', 10, 'hi'] // Error

null 和 undefined

TypeScript里,undefinednull两者各自有自己的类型分别叫做undefinednull

默认情况下 null 和 undefined 是所有类型的子类型。 就是说你可以把 null 和 undefined 赋值给 number 类型的变量。

如果在tsconfig.json配置文件中指定了strictNullChecks: true即开启了严格模式,nullundefined只能赋值给它们各自的类型。

// 启用 strictNullChecks
let x: number; 
x = 1; // OK 

x = undefined; // Type 'undefined' is not assignable to type 'number'
x = null; // Type 'null' is not assignable to type 'number'

特殊的: 严格模式下,undefined可以赋值给void类型。

// 启用 strictNullChecks
let a: void = undefined // OK 
let b: void = null // Type 'null' is not assignable to type 'void'

void 类型

void类型表示:没有任何类型

当一个函数没有返回值时,我们通常将该函数返回值类型定义为void

function func(): void{
    console.log("func")
}

声明一个void类型的变量没有什么用,因为在非严格模式下只能给它赋值undefinednull,严格模式下只能给它赋值undefined

never 类型

never类型表示的是那些永不存在的值的类型。

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

function error(): never {
    throw new Error('err');
}

function infiniteLoop(): never {
    while (true) {
    }
}
const foo = 123;
if(foo !== 123){
    const bar = foo // bar 的类型为 never
}

any类型

如果我们在开发阶段无法确定某个变量的具体类型,我们可以给它使用any关键字,它意味着任何类型any类型会使这些值跳过编译阶段的类型检测器的检查。

let val: any = 6;
val = 'str';
val = [];

console.log(val.attr)
val.func()

any类型的变量还允许直接访问不存在的属性和方法,这样也不会报错。

补充

任何类型的值可以赋值给any类型的变量,同时any类型的值也可以赋值给任何类型(除never类型外)的变量。

并且无视本文中关于void、undefined、null类型中提到的限制,无论是严格或非严格模式下。(也有可能是笔者的测试代码出错或TS版本问题,如有异议可以在评论区中指出,谢谢大佬们)

unknown 类型

TypeScript(3.0 及以上版本)还提供了一种类似于 any 的特殊类型 unknown。我们也可以为 unknown 类型变量分配任何值。

let x: unknown = 1;
x = true
x = 'str'
x = []

unknown 与 any 的区别

  1. 任何类型的值可以赋值给 any 类型的变量,同时 any 类型的值也可以赋值给任何类型的变量。
  2. 任何类型的值可以赋值给 unknown 类型的变量,但 unknown 类型的值只能赋值给 unknown 和 any。
  3. 可以把任何东西分配给 any 类型,也可以对 any 类型进行任何操作
  4. 可以将任何东西赋给 unknown 类型,但在进行类型检查或类型断言之前,不能对 unknown 进行操作。
function func(callback: any){
    callback() // OK
}
func(1)

function func2(callback: unknown){
    callback() // 报错:Object is of type 'unknown'.(2571)
}

function func3(callback: unknown){
    if(typeof callback === 'function'){
        callback() // OK 
    }
}

推荐使用unknown而不是any,因为它提供了更安全的类型:如果想对 unknown 进行操作,必须使用类型断言或缩小到一个特定的类型。