Skip to content

ts 中的变量定义时应该指定数据类型, 并且指定后不能赋值为其他的数据类型, 如果没有指定数据类型会 自动推导变量的数据类型

  • number 数值
  • string 字符串
  • boolean 布尔
  • array 数组
  • object 对象
  • null & undefined 类型值只能是类型本身
  • tuple 元组
  • enum 枚举
  • any 可以是任意类型(不会进行检测)
  • void 没有任何类型, 刚好与 any 相反
  • unknown 未知类型
  • never 不存在的类型, 比如抛出异常
  • 联合类型 多个指定的类型的组合(如: number | string )

自动类型推断

当声明变量没有指定类型的时候, typescript 编译器会根据变量的值来自动推断变量的类型

js
let val1 = 12;
// 自动推断为 let val1: number

let val2 = "hello";
// 自动推断为 let val2: string

let val3 = {
  id: 1001,
  name: "tom",
  friends: [
    { id: 1002, name: "jerry" },
    { id: 1003, name: "spike" },
  ],
};
/*
// 自动推断为 val3
let val3: {
  id: number,
  name: string,
  friends: {
    id: number,
    name: string,
  }[],
}
*/

数值 number

和 js 中的 number 类型是一样的, 只能是数字(包括小数, 整数, 二进制数, 八进制数, bigint)

typescript
let num: number = 1;
num = -1;
num = -1.1;
let num2: bigint = num;

字符串 string

typescript
let str: string = "hello typescript";

布尔值 boolean

typescript
let isDone: boolean = false;
isDone = true;

undefined & null

和 js 中一样, 这两个类型的值就是其本身

typescript
let v1: undefined = undefined;
let v2: null = null;

数组 array

typescript
let numArr: number[];
numArr = [1, 2, 3];
numArr = ["a", 2, 3]; // 报错

let boolArr: Array<boolean> = [];
boolArr = [false, true];
boolArr = [false, 1]; // 报错

let mulArr: (string | number)[]; // 联合类型
mulArr = ["a", 1];
mulArr = ["a", 1, false]; // 报错,只能是 string | number 类型的数据

元组 tuple

元组其实就是数组的扩展类型, 元组用于保存 指定长度和数据类型的 的数据

typescript
let arr: [string, number, boolean];
arr = [false, "a", 1]; // 报错
arr = ["a", 1, false]; // 正确: 必须指定的元素类型必须和定义时的对应

枚举 enum

枚举是 TypeScript 对 JavaScript 数据类型的一个补充

所谓枚举, 就是指那些固定的一些值, 如一个星期只有 7 天, 一年只有 4 个季节, 一年只有 12 个月

  • ts 底层实现 enum 的本质使用 数值来代替, 所以赋值一个数值类型的值给枚举是不会报错的
typescript
enum Gender {
  Man,
  Women,
}

let gender: Gender;
gender = Gender.Man;
gender = Gender.Women;
gender = "男"; // 报错
gender = 0; // 不会报错

任意类型 any

typescript
let val: any = "str";
val = 123;
val = false;
val = [1, 2, 3, 4];

无类型 void

  • javascript 中的 void 运算符

  • 与 any 正好相反, any 表示任何类型, void 表示没有任何类型

  • 在 ts 中一般用于无返回值的函数的类型限定

  • 在 ts 中只有 undefinednull 可以赋值给 void 的变量(严格模式下不能赋值)

typescript
function say(): void {
  console.log("test");
}
say();

未知类型 unknown

Q: unknown 和 any 的区别?

unknown 是不知道类型, 但是一定是有类型的(会检查类型)

any 是任何类型都可以(不会检查类型)

typescript
let val: unknown = "hello";
val.includes("h");

不存在的类型 never

  • never 表示永远不存在值的类型, 或者根本不可能有返回值的函数
typescript
function throwError(): never {
  throw new Error("报错了...");
}

对象 objcet

typescript
// 不限制具体的对象类型
let obj: object = {};
obj = []; // Array 实例对象
obj = new Date(); // Date 实例对象
obj = /\w+/; // Regexp 实例对象
obj = new Number(1); // Number 实例对象
obj = 1; // Type 'number' is not assignable to type 'object'

// 指定具体的对象类型
let date: Date = new Date();
date = /\w+/; // Type 'RegExp' is missing the following properties from type 'Date'

联合类型 union

typescript
let account: number | string = 1101;
account = "account@foxmail.com";

交叉类型

合并多个类型得到新的类型

  • 可以将 interface object 进行属性合并
  • 交叉类型要保证多个类型的一致性(如: object & object, 如果 number & string 将会得到 never 类型)
typescript
interface Animal {
  age: number;
}

interface Things {
  name: string;
}

let obj: Animal & Things = {
  name: "tom",
  age: 11,
};

函数 function

与 JavaScript 不同的是, TypeScript 可以指定 参数类型返回值的类型

参数 & 返回值类型

typescript
// 没有限制参数类型, 得到的结果是不稳定的
function sum(a, b) {
  return a + b;
}
sum(1, 2); // number, 3
sum(1, "2"); // string, 12

// 限制了参数类型, 得到的结果可以自动推导, 也可以手动指定
// 自动推导为 function sum2(x: number, y:number): number
function sum2(x: number, y: number) {
  return x + y;
}

// 手动指定为 string
function sum3(x: number, y: string): string {
  return x + y;
}

// 没有返回值(在 js 中是 undefined)
function showMsg(msg: string): void {
  console.info(msg);
}

// 多个函数的参数相同, 可以指定定义一个 type
type UserParamType = {
  id?: number;
  email: string;
  password: string;
  sex?: string | number;
  avatar?: string;
};

// 创建 & 修改用户方法用的是
function createUser(user: UserParamType): void {}
function updateUser(user: UserParamType): void {}

函数定义

  • ts 的函数和 js 的函数都有 3 种方式, 不同的是, 必须声明参数的类型和返回值的类型
typescript
// 使用 function 关键字
function add(x: number, y: number): number {
  return x + y;
}

// 使用 赋值表达式
const add2 = function (x: number, y: number): number {
  return x + y;
};

// 使用箭头函数
const add3 = (x: number, y: number): number => x + y;

// const add4:Function = (x: number, y: number): number => x + y;

剩余参数

typescript
function sum(...nums: number[]): number {
  let result = 0;
  for (let item of nums) {
    result += item;
  }
  return result;
}

函数重载

typescript
// 重载签名
function getUser(id: string): string;
function getUser(id: number): number;

// 实现函数
function getUser(id: unknown): unknown {
  if (typeof id === "string") {
    return "string-id:" + id;
  }
  return id;
}

console.log(getUser("tom")); // string-id:tom
console.log(getUser(11)); // 11

值类型

typescript
// 1. const 常量, 因为常量是不能更改的, 所以常量只有一个值(也就是说他的类型也是值的类型)
const str = "hello";

// 2. let 将一/多个具体值指定为类型
let str: "hello" | "world" = "hello"; // str只能赋值为 "hello" 或 "world"
str = "world";
str = "hello world"; // error TS2322: Type '"hello world"' is not assignable to type '"hello" | "world"'.

// 3. 未指定类型时,将 let 定义的变量断言为常量
let msg = "hello" as const;
msg = "world"; // Type '"world"' is not assignable to type '"hello"'.

Released under the MIT License.