掌握 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开发干货

相关推荐
weixin_382395233 小时前
为小工厂量身打造:本地部署的物料管理系统带缺料计算
前端·制造
__zRainy__3 小时前
解决pnpm v10+不自动构建
前端·pnpm·工程化
猫猫不是喵喵.4 小时前
Vue3 Props 属性
前端·javascript·vue.js
醉城夜风~5 小时前
CSS元素显示模式(display)
前端·css
AI大模型-小华6 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子8 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅8 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni8 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学10 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端