掌握 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 最强大、最实用的场景。在 switch 或 if/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开发干货

相关推荐
可乐鸡翅yeah_29 分钟前
hls.js 手动自定义 http 请求 loader,修改请求头实战
开发语言·前端·javascript·网络协议·http·ecmascript·m3u8在线
IT_陈寒41 分钟前
Vite静态资源导入这个坑我帮你们踩过了
前端·人工智能·后端
广州华水科技1 小时前
大坝安全监测解决方案:单北斗GNSS形变监测系统应用与维护
前端
yivifu2 小时前
中文古籍电子书注释集成
前端·javascript·python·beautifulsoup·epub
weixin_448290252 小时前
书庐开发实战教学
javascript·css·html
默_笙2 小时前
🛴 从散件到整机:DeepAgents 与 Agent 身上预留的那些"插槽"(前置介绍)
前端·javascript
zhangzeyuaaa3 小时前
深入理解 Ruby 运算符:本质、分类、坑点与重载实战
开发语言·前端·ruby
一木 之林3 小时前
DeepSeek Agent 开发(一)
开发语言·前端·javascript
树下水月4 小时前
Typora破解
linux·服务器·前端
用户5508492902564 小时前
CSS布局实战:从Flex到Grid的完整避坑指南
前端