掌握 TypeScript 的边界:any, unknown, void, never 的正确用法与陷阱

一、 void

void 是我们最常遇到的特殊类型,也是最容易理解的。它表示没有任何返回值

typescript 复制代码
// 这个函数只是打印日志,它不返回任何东西。
function logMessage(message: string): void {
    console.log(message);
    return; // 这个return可有可无,代表什么都不返回
}

let v = void 1; // 此情况比较特殊,代表定义了一个`undefined`变量

解析

  • void: 函数返回使用时代表不返回任何值,变量赋值值,沿袭JavaScript用法,定义了一个undefined变量

二、any

any 是TypeScript中的一把"双刃剑"。它代表任何类型,你可以随意修改他。TypeScript会完全放弃对这个变量的任何类型检查。

typescript 复制代码
let anything: any = "hello";

// 你可以对 a 随意赋值,操作等,在编译期间都不会报错,只有在运行时才会报错
anything = 123;                 // OK
anything = { a: 1 };            // OK
anything.run();                 // OK 
anything.toFixed(2);            // OK 

三、unknown

unknown 也代表任何类型 ,但它是一个类型安全的"任何类型"。

它和 any 的核心区别在于:

  • any 类型的变量,可以被任意操作。
  • unknown 类型的变量,在没有被明确断言或类型收窄 之前,不能进行任何操作
typescript 复制代码
let mystery: unknown = "hello";

// 直接操作会报错!TypeScript 会拦住你。
mystery.toUpperCase(); // Error: mystery类型为未知

// 你必须先证明它的类型
if (typeof mystery === "string") {
    // 在这个代码块里,TypeScript 知道 mystery 是 string 类型
    console.log(mystery.toUpperCase()); // OK!
}

// 另一个关键点:unknown 只能赋值给 any 或 unknown
let str: string = mystery; // Error: 不能将类型"unknown"分配给类型"string"
let anything: any = mystery; // OK

四、never

never 是最特殊的类型。它表示永不存在的值的类型 。和void有点相像,但又有区别。

4.1 抛出错误的函数

一个函数如果总是抛出异常,那么它就永远不会正常返回一个值。它的返回类型就是 never

typescript 复制代码
function throwError(message: string): never {
    throw new Error(message);
}

4.2 无限循环的函数

一个永远不会结束的函数,其返回类型也是 never

typescript 复制代码
function infiniteLoop(): never {
    while (true) {
        // ...
    }
}

4.3 用于类型穷尽检查(Exhaustive Checks)

这是 never 最强大、最实用的场景。在 switchif/else 语句中,我们可以利用 never 来确保我们处理了所有可能的情况。

typescript 复制代码
type Shape = 'circle' | 'square' | 'triangle';

function getArea(shape: Shape): number {
    switch (shape) {
        case 'circle':
            return Math.PI;
        case 'square':
            return 1;
        // case "triangle": return 0.5; // <-- 故意注释掉
        default:
            // 如果我们处理了所有 Shape 的情况,`exhaustiveCheck` 理论上永远不会被执行
            const exhaustiveCheck: never = shape;
            // 如果我们漏掉了 'triangle','shape' 的类型在这里是 'triangle'
            // 将 'triangle' 赋值给 'never' 会导致编译时错误!
            //这就提醒我们必须处理 'triangle' case。
            return exhaustiveCheck;
    }
}

4.4 类型注解

typescript 复制代码
let foo: never; // ok

let foo: never = 123; // Error: number 类型不能赋值给 never 类型

// ok, 作为函数返回类型的 never
let bar: never = (() => {
  throw new Error('Throw my hands in the air like I just dont care');
})();
  • never 类型仅能被赋值给另外一个 never

总结

如果你喜欢本教程,记得点赞+收藏!关注我获取更多JavaScript/TypeScript开发干货

相关推荐
Cocktail_py4 分钟前
JS如何调用wasm
开发语言·javascript·wasm
我有一棵树17 分钟前
深入理解html 加载、解析、渲染和 DOMContentLoaded、onload事件
前端·性能优化·html
JIngJaneIL17 分钟前
就业|高校就业|基于ssm+vue的高校就业信息系统的设计与实现(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·毕设·高校就业
G***T69135 分钟前
前端构建工具环境变量,安全管理
前端
Want5951 小时前
HTML礼物圣诞树
前端·html
REDcker1 小时前
Cursor Chrome DevTools MCP 配置指南 for Windows
前端·windows·chrome devtools
张可爱1 小时前
20251115复盘记录:让分页乖乖“坐好”+ 卡片统一渐变描边与圆角
前端
Jonathan Star1 小时前
基于 **Three.js** 开发的 3D 炮弹发射特效系统
javascript·数码相机·3d
Cache技术分享2 小时前
241. Java 集合 - 使用 Collections 工厂类处理集合
前端·后端
Lear2 小时前
解决Flex布局中overflow:hidden失效
前端