0Pricing
TypeScript Academy · 课时

never 类型与不可能状态

使用 never 对不可达代码和不可能的值进行建模。

never 类型与不可能状态 是 CoddyKit 上的免费 TypeScript Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 TypeScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 TypeScript Academy 课程共包含 4 节课。

never 类型

never 是空类型,表示永远不可能出现的值。没有任何值可以赋给 never(never 自身除外)。它用于标记本应不可能发生的情况。

// You cannot create a value of type never
function crash(): never {
  throw new Error('boom');
}
try { crash(); } catch (e) { console.log('caught'); }

永不返回的函数

始终执行 throw 的函数不会正常返回,因此其返回类型是 never。这会告诉调用者(以及编译器)执行会在此处停止。

function fail(message: string): never {
  throw new Error(message);
}
try { fail('invalid'); } catch (e) { console.log('handled'); }

无限循环返回 never

包含无限循环的函数同样永远不会返回,因此其类型也是 never。编译器能够识别出控制流无法越过该函数继续执行。

function listen(): never {
  while (true) {
    // forever
    break; // (break added so the demo terminates)
  }
  throw new Error('stopped');
}
console.log('listen has return type never');

never 与 void

不要将 never 与 void 混淆。void 函数会返回,只是不会产生有用的值。never 函数则完全不会返回,而是抛出异常或永远循环。

function logIt(): void {
  console.log('done'); // returns normally
}
function abort(): never {
  throw new Error('stop'); // never returns
}
logIt();
try { abort(); } catch (e) { console.log('ok'); }

在穷尽性检查中使用 never

never 最实用的用途是穷尽性检查。在 switch 的默认分支中,将变量赋给 never。如果所有情况都已处理,该变量本身已经是 never,代码就能通过编译。

type Shape = 'circle' | 'square';

function area(s: Shape): string {
  switch (s) {
    case 'circle': return 'pi r^2';
    case 'square': return 'a^2';
    default:
      const _check: never = s; // ok: all handled
      return _check;
  }
}
console.log(area('square'));

捕获遗漏的情况

如果有人新增了联合成员却忘记添加对应分支,剩余值就不再是 never,因此赋值无法通过编译。never 检查会将一个无声的遗漏变成明确的错误。

type Shape = 'circle' | 'square' | 'triangle';
// If 'triangle' case is missing, assigning s to never
// would error: 'triangle' is not assignable to never.
console.log('Add a case for every member');

在不可能的联合分支中使用 never

当类型缩小排除了所有可能性后,剩余类型就是 never。编译器知道该分支无法到达,这可以帮助发现逻辑错误。

function check(x: string | number): void {
  if (typeof x === 'string') {
    console.log('string');
  } else if (typeof x === 'number') {
    console.log('number');
  } else {
    // x is never here
    console.log('unreachable');
  }
}
check('hi');

never 作为底部类型

never 是底部类型:它可以赋给所有其他类型,因为不可能存在的值自然与任何类型都兼容。这就是为什么 throw 可以出现在任何表达式位置。

function getOrThrow(v: string | null): string {
  return v ?? fail();
}
function fail(): never {
  throw new Error('missing');
}
console.log(getOrThrow('value'));

将联合类型过滤为 never

在条件类型和映射类型中,never 起到“移除该项”的作用。与 never 进行联合不会改变任何内容:T | never 就是 T。因此,它自然适合用于过滤。

type Keep<T> = T extends string ? T : never;
type R = Keep<'a' | 1 | 'b'>; // 'a' | 'b'
const x: R = 'a';
console.log(x);

建模不可能的状态

在对象结构中使用 never,可以让非法组合无法表示。在这里,“加载中”状态不能同时携带数据,因为类型禁止了这种组合。

type State =
  | { status: 'loading'; data?: never }
  | { status: 'ready'; data: number };

const s: State = { status: 'ready', data: 7 };
console.log(s);

never 提升重构安全性

由于 never 穷尽性检查会在遗漏分支时失败,因此它能让重构更安全:扩展联合类型后,编译器会指出每个需要更新的位置。

type Cmd = 'start' | 'stop';
function run(c: Cmd): string {
  if (c === 'start') return 'starting';
  if (c === 'stop') return 'stopping';
  const _x: never = c;
  return _x;
}
console.log(run('start'));

快速检查

测试您对 never 类型的理解。

回顾:永不类型

您已学会,never:

  • 是空类型——没有任何值可以属于这种类型。
  • 是会抛出异常或无限循环的函数的返回类型。
  • 为 switch 默认分支中的穷尽性检查提供支持。
  • 会出现在不可能的缩窄分支中,并在类型逻辑中过滤联合类型。

接下来,我们将了解void及其区别。

function assertNever(x: never): never {
  throw new Error('Unexpected: ' + String(x));
}
console.log('assertNever guards exhaustiveness');

常见问题解答

「never 类型与不可能状态」课时是免费的吗?

是的 — 「never 类型与不可能状态」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 TypeScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 TypeScript Academy 课程共包含 4 节课。

「never 类型与不可能状态」这节课中我会学到什么?

使用 never 对不可达代码和不可能的值进行建模。 你通过在浏览器中直接运行的动手代码来练习 TypeScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 TypeScript Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 TypeScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「never 类型与不可能状态」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 TypeScript Academy 课中编写并运行代码吗?

能。每节 TypeScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 理解 unknown 与 any
  2. never 类型与不可能状态
  3. 函数中的 void 类型
  4. 类型安全地处理 unknown
← 返回 TypeScript Academy