你了解TypeScript中的unknown类型吗?

1. unknown 类型的理解

unknown 是 TypeScript 3.0 引入的新的顶级类型,在 TypeScript中,unknown 是所有可能值的集合。任何值都可以分配给 unknown 类型的变量。这意味着 unknown 是所有其他类型的超类型。

2. 可能会出现 unknown 类型的一些情况

2.1. 处理未知类型的函数参数

当编写一个函数,它需要处理多种不同类型的参数,但又无法确定参数的确切类型时,可以使用 unknown 类型来处理未知类型。

typescript 复制代码
const processValue: (value: unknown) => void = value => {
  if (typeof value === "string") {
    console.log("value type is string");
  } else if (typeof value === "number") {
    console.log("value type is number");
  } else if (typeof value === "boolean") {
    console.log("value type is boolean");
  } else {
    // ......
  }
}

processValue(26);     // value type is number
processValue("Echo"); // value type is string

2.2. 从动态内容中获得的值

当通过用户输入、API 响应或从第三方库中获得的值时,可能无法确定其确切类型。此时将值标记为 unknown 可以增加类型的安全性,并要求进行类型检查。

typescript 复制代码
let userInput: unknown = getUserInput();
let apiResponse: unknown = getAPIResponse();

3. unknown 类型的特点

3.1. 任何类型的值都可以赋值给 unknown

typescript 复制代码
let unknown: unknown;
unknown = "Echo";
unknown = 26;
unknown = true;
unknown = {};
unknown = new Array();
unknown = Symbol();
unknown = null;
unknown = undefined;

3.2. unknown 只能赋值自身 和 any 类型的值,不能赋值给其他任何类型。

typescript 复制代码
let unknown: unknown
let un: unknown = unknown       // 正确
let any: any = unknown          // 正确
let str: string = unknown;      // 报错:不能将类型"unknown"分配给类型"string"
let num: number = unknown       // 不能将类型"unknown"分配给类型"number"
let bool: boolean = unknown     // 不能将类型"unknown"分配给类型"boolean"
let func: () => void = unknown  // 不能将类型"unknown"分配给类型"() => void"
let symbol: symbol = unknown    // 不能将类型"unknown"分配给类型"symbol"

3.3. 任何类型与 unknown 的联合类型都是 unknown,除了 any 类型

typescript 复制代码
type T1 = string | unknown       // unknown
type T2 = number | unknown       // unknown
type T3 = boolean | unknown      // unknown
type T4 = symbol | unknown       // unknown
type T5 = bigint | unknown       // unknown
type T6 = never | unknown        // unknown
type T7 = any | unknown          // any
type T8 = {} | unknown           // unknown
type T9 = "Echo" | unknown       // unknown
type T10 = 26 | unknown          // unknown
type T11 = false | unknown       // unknown
type T12 = string[] | unknown    // unknown

3.4. 任何类型与 unknown 的交叉类型都是其本身

typescript 复制代码
type T1 = string & unknown       // string
type T2 = number & unknown       // number
type T3 = boolean & unknown      // boolean
type T4 = symbol & unknown       // symbol
type T5 = bigint & unknown       // bigint
type T6 = never & unknown        // never
type T7 = any & unknown          // any
type T8 = null & unknown         // null
type T9 = undefined & unknown    // undefined
type T10 = {} & unknown          // {}
type T11 = "Echo" & unknown      // "Echo"
type T12 = 26 & unknown          // 26
type T13 = false & unknown       // false
type T14 = string[] & unknown    // string[]

3.5. unknown 可以使用类型断言为其他类型(缩小类型范围)

当使用 unknown 声明一个变量时,TypeScript 不知道它的类型,这意味着我们不能使用它的任何可用方法,除非显式地将其类型"缩小"到特定的类型。

下面示例中,我们使用 as 类型断言将 unknown 类型的变量 value 断言为 string 字符串类型,从而我们可以调用字符串的一些属性和方法。

typescript 复制代码
const value: unknown = "Hello, my name is Echo!";

const str: string = value as string; // 使用类型断言,将 unknown 类型断言为 string 类型
const upperCase = str.toUpperCase();

console.log(upperCase); // HELLO, MY NAME IS ECHO!

3.6. unknown 与 typeof 一起使用(缩小类型范围)

我们都知道,length 是 string 数据类型上可用的属性,我们可以使用下面的代码获取字符串的长度:

typescript 复制代码
const str = "Echo";

console.log(str.length); // 4

下面的示例中,定义一个 checkLength 函数,参数 value 的类型为 unknown 类型,在函数内部打印 value.length,代码将会报错,因为它不确定 .length 属性是否存在于 unknown 类型上。

typescript 复制代码
function checkLength(value : unknown) {
  console.log(value.length); // 报错
}

checkLength("Echo");

要解决此问题,我们可以缩小 value 类型范围并检查该值是否为 string 类型,检查一个值的类型我们可以用 typeof 关键字,下面的代码中,调用 checkLength 函数并传入字符串 "Echo",打印出长度为:4。

typescript 复制代码
function checkLength(value : unknown) {
  if (typeof value === "string") {
    console.log(value.length); // 4
  }
}

checkLength("Echo");

4. unknown 可进行的操作

4.1. 只能进行等于和不等于的判断,其他操作则会报错

typescript 复制代码
function func(x: unknown) {
  x == 5;     // 正确
  x !== 10;   // 正确
  x >= 0;     // Error
  x + 1;      // Error
  x * 2;      // Error
  -x;         // Error
  +x;         // Error
}

4.2. 当解构中有 unknown 类型时,会导致解构出来的结果也是 unknown。

typescript 复制代码
function func(x: {}, y: unknown, z: any) {
  let obj1 = { a: 42, ...x };             // { a: number }
  let obj2 = { a: 42, ...x, ...y };       // unknown
  let obj3 = { a: 42, ...x, ...y, ...z }; // any
}

5. 总结

以上就是我对 TypeScript 中 unknown 类型的理解,如果有不正确的地方,欢迎大家在评论区多多指正!

看完记得点个赞哦~ 谢谢!🤞🤞🤞

相关推荐
也无晴也无风雨1 小时前
深入剖析输入URL按下回车,浏览器做了什么
前端·后端·计算机网络
Martin -Tang1 小时前
Vue 3 中,ref 和 reactive的区别
前端·javascript·vue.js
FakeOccupational3 小时前
nodejs 020: React语法规则 props和state
前端·javascript·react.js
放逐者-保持本心,方可放逐3 小时前
react 组件应用
开发语言·前端·javascript·react.js·前端框架
曹天骄4 小时前
next中服务端组件共享接口数据
前端·javascript·react.js
阮少年、4 小时前
java后台生成模拟聊天截图并返回给前端
java·开发语言·前端
郝晨妤6 小时前
鸿蒙ArkTS和TS有什么区别?
前端·javascript·typescript·鸿蒙
AvatarGiser6 小时前
《ElementPlus 与 ElementUI 差异集合》Icon 图标 More 差异说明
前端·vue.js·elementui
喝旺仔la6 小时前
vue的样式知识点
前端·javascript·vue.js
别忘了微笑_cuicui6 小时前
elementUI中2个日期组件实现开始时间、结束时间(禁用日期面板、控制开始时间不能超过结束时间的时分秒)实现方案
前端·javascript·elementui