Skip to content

准备工作

官网

英文:https://www.typescriptlang.org/ 中文:https://www.tslang.cn/docs/home.html

全局安装

bash
# 全局安装 npm pnpm等
pnpm install -g typescript

# 查看版本
tsc --version

# 编译ts为js
tsc test.ts

基础类型

基本:Number,String,Boolean,undefined,null,Symbol,BigInt 引用:Object

布尔值

typescript
let isDone: boolean = false;

数字

typescript
let decLiteral: number = 6;
let hexLiteral: number = 0xf00d; // 16
let binaryLiteral: number = 0b1010; // 2
let octalLiteral: number = 0o744; // 8进制

字符串

typescript
// 单双引号,模板字符串都可以
const name: string = "bob";
name = "smith";

const name: string = `Gene`;

数组

两种方式定义数组

  1. 元素类型后面跟上 []
  2. 使用数组泛型
typescript
// 数组里面每个元素为number
let list: number[] = [1, 2, 3];  
let list: Array<number> = [1, 2, 3];

// 第一种用得多一些
const arr1: string[] = [];
const arr2: Array<string> = [];

元组 Tuple

在某些情况下,使用 元组(Tuple) 来代替数组要更加妥当,比如一个数组中只存放固定长度的变量,但我们进行了超出长度地访问:

typescript
const arr3: string[] = ['lin', 'bu', 'du'];

console.log(arr3[599]);

因为我们能确定这个数组中只有三个成员,并希望在越界访问时给出类型报错。这时我们可以使用元组类型进行类型标注:

typescript
const arr4: [string, string, string] = ['lin', 'bu', 'du'];

console.log(arr4[599]);
// Error 
// 长度为“3”的元组类型“[string, string, string]”
// 在索引“599“处没有元素。

元组:已知元素数量和类型的数组。

定义一对值分别为 string和number类型的元组。

typescript
let x: [string, number] = ['hello', 10] // ok
x = [10, 'hello']; // Error 

// 当访问一个越界的元素,会使用联合类型替代
x[3] = 'world'; 
// OK, 字符串可以赋值给(string | number)类型

枚举

使用枚举类型可以为一组数值赋予友好的名字。 默认情况,枚举成员的值是从0开始递增的

typescript
// 定义一个颜色的枚举
enum Color {
  Red,
  Green,
  Blue
}

// 使用枚举
let myColor: Color = Color.Green;
console.log(myColor); // 输出: 1,因为 Green 对应的值是 1
typescript
// 手动指定枚举成员的值
enum Color {
  Red = 1,
  Green = 2,
  Blue = 4
}

let myColor: Color = Color.Green;
console.log(myColor); // 输出: 2

定义使用

typescript
enum Direction {
  Up = 1,
  Down = 2,
  Left = 3,
  Right = 4
}
let useDirection: Direction = Direction.up
console.log(userDirection); // 输出: 1

// 通过值,获取枚举成员名称
let directionName: string = Direction[2];
console.log(directionName); // 输出: Down

使用例子

表示状态

typescript
enum GameState {
  Loading,
  Playing,
  Paused,
  GameOver
}

let currentGameState: GameState = GameState.Playing;

if (currentGameState === GameState.Playing) {
  console.log("Game is currently playing");
}

表示错误码

typescript
enum ErrorCode {
  NotFound = 404,
  Unauthorized = 401,
  InternalServerError = 500
}

function handleError(errorCode: ErrorCode): void {
  console.log(`Error ${errorCode}: ${getErrorMessage(errorCode)}`);
}

function getErrorMessage(errorCode: ErrorCode): string {
  switch (errorCode) {
    case ErrorCode.NotFound:
      return "Not Found";
    case ErrorCode.Unauthorized:
      return "Unauthorized";
    case ErrorCode.InternalServerError:
      return "Internal Server Error";
    default:
      return "Unknown Error";
  }
}

handleError(ErrorCode.Unauthorized);

常熟枚举

typescript
const enum Constants {
  PI = 3.14,
  E = 2.718
}

let circumference = Constants.PI * 2 * radius;

Any

any 类型可以用来表示任意类型的值,允许在编码时绕过类型检查系统

typescript
let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean

let list: any[] = [1, true, "free"];
list[1] = 100;

Void

void类型像是与any类型相反,它表示没有任何类型. void 类型通常用于表示函数没有返回值。

typescript
function logMessage(message: string): void {
  console.log(message);
}

let result: void = logMessage("Hello, TypeScript!"); 
// 函数没有返回值,result 的值只能是 undefined 或 null

函数声明时使用void

typescript
function doSomething(): void {
  // 一些操作
}

函数表达式中使用

typescript
let myFunction: () => void = function() {
  // 一些操作
};

类方法中

typescript
class Example {
  performAction(): void {
    // 一些操作
  }
}

void变量

声明一个void类型的变量没有什么大用

对于变量的类型来说,void 只能接受 undefinednull。如果一个函数返回 void,则调用该函数的结果将是 undefined

typescript
let unusable: void = undefined; // null 

// 需要关闭 strictNullChecks
const voidVar1: void = undefined;
const voidVar2: void = null;

Null 和 Undefined

typescript
// Not much else we can assign to these variables!
let u: undefined = undefined;
let n: null = null;

undefined

undefined 类型表示一个变量尚未被赋值或一个属性不存在。

typescript
let variable: undefined;
console.log(variable); // 输出: undefined

let obj: { prop?: string } = {};
console.log(obj.prop); // 输出: undefined

null

null 类型表示一个变量被明确赋值为 null

typescript
let nullableValue: null = null;
console.log(nullableValue); // 输出: null

联合类型

可以使用联合类型来表示一个值可以是 undefinednull

typescript
let union: string | undefined | null;
union = "some value";
union = undefined;
union = null;

默认情况

当你声明一个变量但没有明确指定类型时,它的类型会被默认为 undefinednull 的联合类型,具体取决于你的 TypeScript 配置:

typescript
let defaultUndefined; // 默认类型是 undefined
let defaultNull = null; // 类型是 null

非严格模式

在非严格模式下,undefinednull 是所有类型的子类型,这意味着你可以将它们赋值给任何类型的变量。

typescript
// 仅在关闭 strictNullChecks 时成立
let str: string = undefined;
let num: number = null;

const tmp1: null = null;
const tmp2: undefined = undefined;

// 仅在关闭 strictNullChecks 时成立
const tmp3: string = null; 
const tmp4: string = undefined;

严格模式

undefinednull 只能分别赋值给它们对应的类型,而不能赋值给其他类型的变量,除非使用联合类型。

typescript
let str: string = undefined; // Error in strict mode
let num: number = null; // Error in strict mode

总的来说,在 TypeScript 中,undefinednull 用于表示缺失或未赋值的状态,

Never

在 TypeScript 中,never 是一个表示永远不会有返回值的类型。 通常用于标识函数抛出异常、进入无限循环或者总是抛出错误的情况。 never 类型可以作为任何类型的子类型。

函数抛出异常

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

// 这个函数永远不会正常返回
let result: never = throwError("Something went wrong");

函数进入无限循环

typescript
function infiniteLoop(): never {
  while (true) {
    // 无限循环
  }
}

// 这个函数永远不会正常返回
let result: never = infiniteLoop();

Object

object 是一种表示非原始数据类型的类型。 它包括数组、函数、以及具有属性和方法的对象。object 类型是一个相对宽泛的类型,可以用来表示不特定结构的对象。

基本用法

typescript
let myObject: object = { key: "value" };  // 对象
let myArray: object = [1, 2, 3];  // 数组
let myFunction: object = () => console.log("Hello"); // 函数

// 特定结构的对象
let person: object = { name: "John", age: 30 };
let point: object = { x: 10, y: 20 };
// 限制结构的对象
let limitedObject: { key: string } = { key: "value" };

object 类型不包括原始数据类型(如字符串、数字、布尔等)。如果你想表示任何类型,包括原始数据类型,你可以使用 any 类型。

typescript
let anyObject: any = "This is a string";
let anyObject2: any = 42;
// 在实际开发中,更推荐使用更具体的类型来描述对象的结构,

类型断言

告诉编译器某个值的具体类型的方法。 “相信我,我知道自己在干什么”。 类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构。有两种形式

尖括号语法

typescript
let someValue: any = "This is a string";

// 将 someValue 断言为 string 类型
let strLength: number = (<string>someValue).length;

console.log(strLength); // 输出: 16

as关键字

typescript
let someValue: any = "This is a string";

// 将 someValue 断言为 string 类型
let strLength: number = (someValue as string).length;

console.log(strLength); // 输出: 16

someValue 是一个 any 类型的变量,我们希望将其断言为 string 类型,以便可以调用字符串的 length 属性。类型断言告诉 TypeScript 编译器:“相信我,我知道这个变量的类型是什么。”

非空断言

非空断言告诉编译器,你确认值不会是 nullundefined

有时候你可能知道一个值不会是 nullundefined,但 TypeScript 编译器仍然会发出警告。在这种情况下,可以使用非空断言 !

typescript
let value: string | null = "Hello";
let length: number = (value as string).length; // 编译器会警告
let lengthWithoutWarning: number = (value! as string).length; // 使用非空断言,消除警告