Skip to content

特殊类型

  • any:任意类型(关闭类型检查)
  • unknown:未知类型(比 any 更安全,需要类型缩小)
  • never:永远不会有值(函数抛异常或死循环的返回类型)
  • void:没有返回值(常用于函数返回类型)

any

  • 含义:表示任意类型,赋值时类型检查。
  • 特点:编译器完全放弃检查,你可以对 any 类型的值做任何事。
  • 危险性:容易引入 bug。
ts
let value: any;

value = 123;
value = 'hello';
value = { foo: 'bar' };

// 可以随便用,不会报错
value();
value.toUpperCase();
value.nonExist.prop.deep;

unknown

  • 含义:任意类型,但是会开启类型检查
  • 特点:你不能直接对 unknown 做任何操作,必须先 类型缩小(type narrowing)。
  • 优势:强制开发者进行类型检查。
特性anyunknown
类型检查关闭检查需要缩小后才能用
可赋值性可赋值给任意类型只能赋值给 anyunknown
安全性不安全,容易出 bug更安全,强制类型守卫
使用场景临时跳过检查、快速原型开发处理外部数据(如接口返回值)
ts
let value: unknown;

value = 123;
value = 'hello';
value = { foo: 'bar' };

// ❌ 报错:不能直接操作 unknown
// value.toUpperCase();

// ✅ 必须先缩小类型
if (typeof value === 'string') {
  console.log(value.toUpperCase()); // ok
}

never

never:空范围,产生于不合理的类型运算

可以赋值给任何类型,但没有任何类型能赋值给它(除了 never 本身)。

ts
type A=number & string

A会被编译器推断为never类型,因为不存在一个值既可以是number类型又是string类型

ts
let a: never;
// a = 123; // ❌ 报错
// a = "hello"; // ❌ 报错
// a = undefined; // ❌ 报错

应用场景:

  1. 抛出异常的函数
ts
function error(message: string): never {
  throw new Error(message);
}
  1. 检查不可达分支

    如果触发default,说明存在业务逻辑错误,需要我们完善代码

ts
type Shape = "circle" | "square";

function getArea(shape: Shape) {
  switch(shape) {
    case "circle": return Math.PI;
    case "square": return 1;
    default:
      const _exhaustiveCheck: never = shape; // ❌ 如果有新成员报错
      return _exhaustiveCheck;
  }
}

模板字面量类型

模板字面量类型是 TS 4.1 引入的类型。它允许你把字面量类型像 JS 模板字符串一样拼接、裁剪、变换,最终得到一个新的字符串字面量类型集合

  1. 语法与 JS 模板字符串一模一样
ts
type World = "world";
type Greeting = `hello ${World}`;   // "hello world"
  1. 拼接的“变量”只能是字面量类型或其联合
ts
type Method = "GET" | "POST";
type Endpoint = `/${Method}/user`;  // "/GET/user" | "/POST/user"
  1. 支持 string, number, boolean, bigint 占位符
ts
type Verbose = `id-${string}`;      // 任意以 "id-" 开头的字符串
type N = `item-${number}`;          // "item-0", "item-1", …
  1. 配合 infer 做“字符串模式匹配”——类型层面的正则
ts
type ExtractId<T> = T extends `id-${infer Id}` ? Id : never;

type T1 = ExtractId<"id-123">;      // "123"
type T2 = ExtractId<"user-456">;    // never
  1. keyof 交叉,精准筛选对象键
ts
type Props = {
  onClick: () => void;
  onHover: (e: Event) => void;
  name: string;
};

type EventHandlers = keyof Props & `on${string}`;
// "onClick" | "onHover"