TypeScript-infer关键字和TypeScript-unknown类型

简介: TypeScript-infer关键字和TypeScript-unknown类型

infer 关键字


条件类型提供了一个 infer 关键字, 可以让我们在条件类型中定义新的类型

博主假设有这么一个需求: 定义一个类型, 如果传入的是数组, 就返回数组的元素类型, 如果传入的是普通类型, 则直接返回这个类型。


传入的是数组:

type MyType<T> = T extends any[] ? T[number] : T;
type res = MyType<string[]>;


传入的是普通类型:

type MyType<T> = T extends any[] ? T[number] : T;
type res = MyType<number>;


除了如上的实现方式以外,还可以利用 infer 关键字来实现。

传入的是数组:

type MyType<T> = T extends Array<infer U> ? U : T;
type res = MyType<string[]>;


传入的是普通类型:

type MyType<T> = T extends Array<infer U> ? U : T;
type res = MyType<number>;




unknown 类型


unknown 类型是 TS3.0 中新增的一个顶级类型, 被称作安全的 any

任何类型都可以赋值给 unknown 类型:

let value: unknown;
value = 123;
value = "abc";
value = false;


如果没有类型断言或基于控制流的类型细化, 那么不能将 unknown 类型赋值给其它类型。

错误示例:

let value1: unknown = 123;
let value2: number;
value2 = value1;


正确示例:

let value1: unknown = 123;
let value2: number;
value2 = value1 as number;


let value1: unknown = 123;
let value2: number;
if (typeof value1 === 'number') {
    value2 = value1;
}


如果没有类型断言或基于控制流的类型细化, 那么不能在 unknown 类型上进行任何操作。

错误示例:

let value1: unknown = 123;
value1++;


正确示例:

let value1: unknown = 123;
(value1 as number)++;


let value1: unknown = 123;
if (typeof value1 === 'number') {
    value1++;
}


只能对 unknown 类型进行 相等不等 操作, 不能进行其它操作(因为其他操作没有意义)。

正确示例:

let value1: unknown = 123;
let value2: unknown = 123;
console.log(value1 === value2);
console.log(value1 !== value2);


不能进行其它操作(因为其他操作没有意义), 虽然没有报错, 但是不推荐, 如果想报错提示, 可以打开严格模式("strict": true):

let value1: unknown = 123;
let value2: unknown = 123;
console.log(value1 >= value2);


unknown 与其它任何类型组成的交叉类型最后都是其它类型:

type MyType = number & unknown;
type MyType = unknown & string;


unknown 除了与 any 以外, 与其它任何类型组成的联合类型最后都是 unknown 类型:

type MyType1 = unknown | any;
type MyType2 = unknown | number;
type MyType3 = unknown | string | boolean;


never 类型是 unknown 类型的子类型:

type MyType = never extends unknown ? true : false;


keyof unknown 等于 never:

type MyType = keyof unknown;


unknown 类型的值不能访问创建实例的属性, 方法:

class Person {
    name: string = 'yangbuyiya';
    say(): void {
        console.log(`name = ${this.name}`);
    }
}
let p: unknown = new Person();
p.say();
console.log(p.name);


使用映射类型时, 如果遍历的是 unknown 类型, 那么不会映射任何属性:

type MyType<T> = {
    [P in keyof T]: any
}
type res = MyType<unknown>


最后

本期结束咱们下次再见👋~

🌊 关注我不迷路,如果本篇文章对你有所帮助,或者你有什么疑问,欢迎在评论区留言,我一般看到都会回复的。大家点赞支持一下哟~ 💗

相关文章
|
1月前
|
JavaScript
typeScript进阶(9)_type类型别名
本文介绍了TypeScript中类型别名的概念和用法。类型别名使用`type`关键字定义,可以为现有类型起一个新的名字,使代码更加清晰易懂。文章通过具体示例展示了如何定义类型别名以及如何在函数中使用类型别名。
36 1
typeScript进阶(9)_type类型别名
|
1月前
|
JavaScript
typeScript基础(2)_any任意值类型和类型推论
本文介绍了TypeScript中的`any`任意值类型,它可以赋值为其他任何类型。同时,文章还解释了TypeScript中的类型推论机制,即在没有明确指定类型时,TypeScript如何根据变量的初始赋值来推断其类型。如果变量初始化时未指定类型,将被推断为`any`类型,从而允许赋予任何类型的值。
52 4
|
9天前
|
JavaScript 前端开发 安全
深入理解TypeScript:增强JavaScript的类型安全性
【10月更文挑战第8天】深入理解TypeScript:增强JavaScript的类型安全性
18 0
|
9天前
|
JavaScript 前端开发 开发者
深入理解TypeScript:类型系统与实用技巧
【10月更文挑战第8天】深入理解TypeScript:类型系统与实用技巧
|
1月前
|
JavaScript
typeScript基础(5)_对象的类型-interfaces接口
本文介绍了TypeScript中接口(interfaces)的基本概念和用法,包括如何定义接口、接口的简单使用、自定义属性、以及如何使用`readonly`关键字定义只读属性。接口在TypeScript中是定义对象形状的重要方式,可以规定对象的必有属性、可选属性、自定义属性和只读属性。
34 1
|
1月前
|
存储 JavaScript
typeScript进阶(11)_元组类型
本文介绍了TypeScript中的元组(Tuple)类型,它是一种特殊的数组类型,可以存储不同类型的元素。文章通过示例展示了如何声明元组类型以及如何给元组赋值。元组类型在定义时需要指定数组中每一项的类型,且在赋值时必须满足这些类型约束。此外,还探讨了如何给元组类型添加额外的元素,这些元素必须符合元组类型中定义的类型联合。
41 0
|
1月前
|
JavaScript
typeScript进阶(10)_字符串字面量类型
本文介绍了TypeScript中的字符串字面量类型,这种类型用来限制变量只能是某些特定的字符串字面量。通过使用`type`关键字声明,可以确保变量的值限定在预定义的字符串字面量集合中。文章通过示例代码展示了如何声明和使用字符串字面量类型,并说明了它在函数默认参数中的应用。
30 0
|
4天前
|
JavaScript 前端开发
TypeScript【类型别名、泛型】超简洁教程!再也不用看臭又长的TypeScript文档了!
【10月更文挑战第11天】TypeScript【类型别名、泛型】超简洁教程!再也不用看臭又长的TypeScript文档了!
|
7天前
|
JavaScript 前端开发 安全
TypeScript【基础类型】超简洁教程!再也不用看臭又长的TypeScript文档了!
【10月更文挑战第9天】TypeScript【基础类型】超简洁教程!再也不用看臭又长的TypeScript文档了!
|
9天前
|
JavaScript 前端开发 开发者
深入理解TypeScript:类型系统与最佳实践
【10月更文挑战第8天】深入理解TypeScript:类型系统与最佳实践