摘要:在本教程中,您将学习 TypeScript 未知类型,以强制执行未知值的类型检查。
TypeScript 未知类型的介绍
在 TypeScript 中,unknown
类型可以保存一个预先未知但需要类型检查的值。
要声明一个 unknown
类型的变量,您可以使用以下语法
let result: unknown;
Code language: TypeScript (typescript)
与 any 类型 一样,您可以将任何值分配给 unknown
类型的变量。例如
let result: unknown;
result = 1;
result = 'hello';
result = false;
result = Symbol();
result = { name: 'John' };
result = [1, 2, 3];
Code language: TypeScript (typescript)
与 any
类型不同,TypeScript 在对其执行操作之前会检查类型。
例如,您不能在 unknown
值上调用方法或应用运算符。如果尝试这样做,TypeScript 编译器将发出错误
let result: unknown;
result = [1,2,3];
const total = result.reduce((a: number, b:number ) => a + b, 0);
console.log(total);
Code language: TypeScript (typescript)
在此示例中,result
变量的类型为 unknown
。我们将一个数组赋值给 result
变量,但其类型仍然为 unknown
。因此,我们无法在其上调用数组的 reduce()
方法。
要调用 result
变量上的 reduce()
方法,您需要使用 类型断言 明确告诉 TypeScript 编译器 result
的类型为 数组。例如
let result: unknown;
result = [1, 2, 3];
const total = (result as number[]).reduce((a: number, b: number) => a + b, 0);
console.log(total); // 6
Code language: TypeScript (typescript)
在此示例中,我们明确告诉 TypeScript 编译器 result
的类型为数字数组 (result as number[]
)。
因此,我们可以毫无问题地调用 result
数组上的 reduce()
方法。
unknown 与 any 类型
下表重点介绍了 unknown
和 any
类型之间的主要区别
特性 | any | unknown |
---|---|---|
类型安全 | 无类型安全 | 强制执行类型安全 |
操作 | 可以在没有检查的情况下执行操作 | 在没有类型断言(类型缩小)的情况下无法执行操作 |
用例 | 对动态值很有用,但不安全。 | 对动态值很有用且安全,因为它需要在使用前进行验证。 |
类型检查 | TypeScript 编译器不会对 any 变量执行类型检查。 | TypeScript 编译器会对 unknown 变量强制执行类型检查。 |
常见场景 | 用于将 JavaScript 代码库迁移到 TypeScript。 | 在处理来自外部源(API 调用、数据库等)的数据时使用,在这些数据中需要类型验证。 |
TypeScript 未知类型示例
让我们来看一些使用 Typescript unknown
类型的实用示例。
1) 处理外部数据
在从外部 API 接收数据时,您可以使用 unknown
类型在处理数据之前强制执行验证。
以下示例演示了如何使用 fetch 方法 从 https://jsonplaceholder.typicode.com/posts
端点调用 API
const fetchData = async (url: string): Promise<unknown> => {
const response = await fetch(url);
return await response.json();
};
const showPosts = async () => {
const url = 'https://jsonplaceholder.typicode.com/posts';
try {
const posts = await fetchData(url); // unknown type
(
posts as { userId: number; id: number; title: string; body: string }[]
).map((post) => console.log(post.title));
} catch (err) {
console.log(err);
}
};
showPosts();
Code language: TypeScript (typescript)
工作原理。
首先,定义一个函数 fetchData
,它从 URL 调用 API 并返回 JSON 数据。由于返回数据的形状未知,因此函数返回一个 Promise<unknown>
值
const fetchData = async (url: string): Promise<unknown> => {
const response = await fetch(url);
return await response.json();
};
Code language: TypeScript (typescript)
其次,定义 showPosts()
函数,它使用 fetchData()
函数从 https://jsonplaceholder.typicode.com/posts
端点调用 API
const showPosts = async () => {
const url = 'https://jsonplaceholder.typicode.com/posts';
try {
const posts = await fetchData(url); // unknown type
(
posts as { userId: number; id: number; title: string; body: string }[]
).map((post) => console.log(post.title));
} catch (err) {
console.log(err);
}
};
Code language: TypeScript (typescript)
在此示例中,posts 变量的类型为 unknown。
在访问其 title
属性之前,我们使用 类型断言 指示 TypeScript 编译器将其视为帖子对象的数组
posts as { userId: number; id: number; title: string; body: string }[]
Code language: TypeScript (typescript)
第三,调用 showPosts()
函数
showPosts();
Code language: TypeScript (typescript)
2) 创建类型安全的接口
以下示例定义了一个函数 format
,它在将值记录到控制台之前对其进行格式化
function format(value: unknown): void {
switch (typeof value) {
case 'string':
console.log('String:', value.toUpperCase());
break;
case 'number':
console.log('Number:', value.toFixed(2));
break;
default:
console.log('Other types:', value);
}
}
Code language: TypeScript (typescript)
在此示例中,在访问值的某个方法之前,我们验证其类型以确保操作有效。
总结
unknown
类型类似于 any 类型,但更严格。- 使用
unknown
类型来处理来自外部源的数据,并在使用前需要验证。