TypeScript 未知类型

摘要:在本教程中,您将学习 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); // 6Code language: TypeScript (typescript)

在此示例中,我们明确告诉 TypeScript 编译器 result 的类型为数字数组 (result as number[])。

因此,我们可以毫无问题地调用 result 数组上的 reduce() 方法。

unknown 与 any 类型

下表重点介绍了 unknownany 类型之间的主要区别

特性anyunknown
类型安全无类型安全强制执行类型安全
操作可以在没有检查的情况下执行操作在没有类型断言(类型缩小)的情况下无法执行操作
用例对动态值很有用,但不安全。对动态值很有用且安全,因为它需要在使用前进行验证。
类型检查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 类型来处理来自外部源的数据,并在使用前需要验证。
本教程是否有帮助?