前言
- 常网IT源码上线啦!
- 本篇录入技术选型专栏,希望能祝君拿下Offer一臂之力,各位看官感兴趣可移步🚶。
- 有人说面试造火箭,进去拧螺丝;其实个人觉得问的问题是项目中涉及的点 || 热门的技术栈都是很好的面试体验,不要是旁门左道冷门的知识,实际上并不会用到的。
- 接下来想分享一些自己在项目中遇到的技术选型以及问题场景。
代码敲着敲着便有点感悟。
人生的路,没有标准答案,也没有永远正确的导航系统。我们唯一能做的,就是像一个优秀的程序员对待自己编写的代码一样,不断去认识自己,了解自己的优点和缺点,知道自己内心深处真正想要什么,又在恐惧什么。然后,根据这些认知,去调整自己的行为模式,优化自己的"人生算法"。

一、前言
TypeScript相信已经挺成熟了,再众多项目中都用上了,虽然工作量是增大了,但总体利大于弊。
还是得学。
得用。
直入正文。
any void never unknown 有什么区别?
以及在什么场景上用哪个,这篇一定给各位讲懂。
二、any void never unknown
主要区别:
-
any
任意类型(不进行类型检查) -
void
没有任何类型,和any
相反 -
never
永不存在的值的类型 -
unknown
未知类型(一个更安全的 any)
代码示例:
java
function fn(): void {} // void 一般定义函数返回值
// 返回 never 的函数,必须存在无法达到的终点
function error(msg: string): never {
throw new Error(msg)
}
function infiniteLoop(): never {
while (true) {}
}
const car: any = 'baoma'
console.log(car.toUpperCase()) // 不会报错,但不安全
// unknown 比直接使用 any 更安全
const bicycle: unknown = '单车'
// console.log( bicycle.toUpperCase() ) // 会报错!!!
console.log((bicycle as string).toUpperCase()) // 使用 as 转换类型,意思是告诉 TS 编译器:"我知道 bicycle 的类型,我对安全负责"
接着主要讲一下never
和unknown
,这两个的场景稍微比较难理解。
三、never
表示永远不会出现的值类型。
java
// 1. 不可能返回的函數
function error(message: string): never {
throw new Error(message);
}
// 2. 无限循环
function infiniteLoop(): never {
while(true) {}
}
// 3. 类型收窄终极判断
type All = string | number
function check(type: All) {
if (typeof type === "string") {
// 这里 type 是 string
} else if (typeof type === "number") {
// 这里 type 是 number
} else {
// 这里 type 是 never
const unreachable: never = type
}
}
进阶应用场景:
- 排除联合类型中的特定类型
java
type T = Exclude<string | number | boolean, number> // string | boolean
- 空对象过滤(工具类型实现)
java
type NonNullable<T> = T extends null | undefined ? never : T
// 作用:过滤类型中的 null 和 undefined
// 应用:
type T1 = string | null | undefined
type CleanT1 = NonNullable<T1> // 最终类型变成 string
type T2 = number[] | undefined
type CleanT2 = NonNullable<T2> // 最终类型变成 number[]
- 类型映射过滤(删除属性)
java
type RemoveKindField<T> = {
[K in keyof T as Exclude<K, "kind">]: T[K]
}
// 作用:移除对象类型中的 kind 属性
interface Device {
kind: string;
id: number;
name: string;
}
type CleanDevice = RemoveKindField<Device>
/* 结果类型:
{
id: number;
name: string;
}
*/
- 联合类型完整性检查
java
type Animal = "cat" | "dog"
function handleAnimal(animal: Animal) {
switch(animal) {
case "cat": break
case "dog": break
default:
const _exhaustiveCheck: never = animal // 如果 Animal 新增类型会报错
}
}
在业务代码中的实际应用:
java
// 类型安全的对象属性访问
function getSafeValue<T, K extends keyof T>(obj: T, key: K): T[K] | never {
if (!(key in obj)) {
throw new Error(`属性 ${String(key)} 不存在`)
}
return obj[key]
}
// 应用在你的 fillLevel 对象
const level = getSafeValue(fillLevel, 2) // 正确:"省级"
const invalid = getSafeValue(fillLevel, 7) // 编译时报错 + 运行时报错
讲了这么多,其实never
类型的主要作用是:
-
增强类型安全性,确保代码覆盖所有可能情况
-
在类型系统中实现更精确的类型操作
-
标识不可达代码路径,帮助发现逻辑错误
-
作为类型运算的底层标识(如条件类型中的最终分支)
四、unknown
未知的值类型。它比 any
更安全,因为使用前必须进行类型检查或断言。
安全容器特性:
java
let value: unknown;
// 合法操作
value = 42; // 可接收任何类型
value = "hello";
value = new Date();
// 非法操作(直接使用会报错)
value.trim(); // Error: Object is of type 'unknown'
value.toFixed(2); // Error
与 any 的区别
java
function exampleAny(val: any) {
val.trim(); // 不报错(危险!)
}
function exampleUnknown(val: unknown) {
val.trim(); // Error: 必须类型检查
}
类型收窄实践
java
function parseJSON(jsonString: string): unknown {
return JSON.parse(jsonString);
}
// 使用示例
const data = parseJSON('{"name": "John", "age": 30}');
if (data &&
typeof data === "object" &&
"name" in data &&
typeof data.name === "string" &&
"age" in data &&
typeof data.age === "number") {
// 此时 data 被收窄为 { name: string; age: number }
console.log(data.name.toUpperCase()); // 安全调用
console.log(data.age.toFixed(2)); // 安全调用
}
应用场景
假设需要处理动态表格数据时:
java
// 从后端接口获取不确定结构的响应
async function fetchDynamicData(): Promise<unknown> {
const response = await fetch('/api/endpoint');
return response.json();
}
// 安全使用方式
const data = await fetchDynamicData();
if (typeof data === 'object' && data !== null && 'rows' in data) {
// 在此处进行更精确的类型断言或类型守卫
const tableData = data as { rows: Array<{ [key: string]: unknown }> };
// 进一步处理表格数据...
}
平时怎么用:
-
优先使用
unknown
替代any
-
与类型守卫(Type Guard)配合使用
-
处理第三方库或外部输入时作为中间类型
-
最终通过类型断言收窄到具体类型
至此撒花~
后记
TypeScript主要是类型的理解,多用,多查一下,会发现,也还行。
我是Dignity_呱,来交个朋友呀,有朋自远方来,不亦乐乎呀!深夜末班车
👍 如果对您有帮助,您的点赞是我前进的润滑剂。
以往推荐
vue2和Vue3和React的diff算法展开说说:从原理到优化策略
玩转Vue插槽:从基础到高级应用场景(内含为何Vue 2 不支持多根节点)