su37josephxia / frontend-interview

前端面试知识点
MIT License
159 stars 45 forks source link

TS中any与unkonow与never类型都是什么 #144

Open su37josephxia opened 2 years ago

ruixue0702 commented 2 years ago

TS中any与unkonow与never类型都是什么 ?

any || unknown —— 顶层类型 never —— 底层类型

any(不建议): 任意类型,包含了Javascript中的所有类型的值 unknown: 未知类型,可以接受任意类型的值(可以把 unknow 理解为是安全的 any 类型) never: 不包含任何类型的值的类型(所有类型的子类型,可以赋值给任何其他类型,但是任何类型都不能赋值给never)

RJM1996 commented 2 years ago

any、never、unknow

any

any 是任意值类型,定义为 any 类型的变量允许被赋值为任意类型。

let myFavoriteNumber: any = 'seven'
myFavoriteNumber = 7

变量如果在声明的时候,未指定其类型,那么它会被识别为任意值类型,也就是说声明为 any 类型和写 JS 没啥区别

never

never 类型表示的是那些永不存在的值的类型。例如一个抛出异常的函数,一个永远不会返回的函数的返回值类型

// 返回never的函数必须存在无法达到的终点
function error(message: string): never {
  throw new Error(message)
}

// 推断的返回值类型为never
function fail() {
  return error('Something failed')
}

// 返回never的函数必须存在无法达到的终点
function infiniteLoop(): never {
  while (true) {}
}

never 类型是任何类型的子类型,可以赋值给任意类型。但是没有类型是 never 类型的子类型,即使是 any 类型也不能赋值给 never 类型

unknown

unknown 类型是 ts 中所有基础类型的父类型,所有基础类型都能赋值为 unknown 类型。

但是当 unknown 类型赋值为其他任意类型时,就会进行类型检查。我们必须将这个 unknown 类型的变量断言为具体的类型,才可以继续使用。

所以 any 和 unknown 的区别就是:

二者都是可以赋值给任意类型的, any 会绕过类型检查,直接可用;而 unkonwn 则必须要在判断完它是什么类型之后才能继续使用

chunhuigao commented 2 years ago

any

任意类型,TS的默认类型。不作任何约束,编译时会跳过对其的类型检查

unknown

未知类型;能被赋值为任何类型,但不能被赋值给除了 any 和 unknown 之外的其他类型

never

不存在的类型;可以赋值给任何类型,但是不能被任意类型赋值

QbjGKNick commented 2 years ago

any

any 表示任意类型,不做任何约束,编译的时候会跳过对其的类型检查

let val: any;
val = 1;
val = 'abc';
val = false

上面编译通过,由于 val 是any类型,自动跳过检查。

void

void 表示无任何类型,即没有类型,如果变量申明了 void 类型,则只能给这个变量分配 undefinednullvoid类型的值,如果ts 配置文件中设置了"strictNullChecks": false,则给变量分配null类型的值会报错

unknown

unknow类型表示未知类型,它能被赋值为任何类型,但是不能被赋值给除了 anyunknown 之外的其它类型

never

never 表示 用不存在的值的类型,可以赋值给任何类型,但是不能被任意类型赋值

JanusJiang1 commented 2 years ago

any:

任意类型,它允许你在编译时可选择地包含或移除类型检查。 你可能认为 Object有相似的作用,就像它在其它语言中那样。 但是 Object类型的变量只是允许你给它赋任意值 - 但是却不能够在它上面调用任意的方法,即便它真的有这些方法:

let notSure: any = 4;
notSure.ifItExists(); // okay, ifItExists might exist at runtime
notSure.toFixed(); // okay, toFixed exists (but the compiler doesn't check)

let prettySure: Object = 4;
prettySure.toFixed(); // Error: Property 'toFixed' doesn't exist on type 'Object'.

never:

never类型表示的是那些永不存在的值的类型。 例如, never类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型; 变量也可能是 never类型,当它们被永不为真的类型保护所约束时。

never类型是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是never的子类型或可以赋值给never类型(除了never本身之外)。 即使 any也不可以赋值给never。

下面是一些返回never类型的函数:

// 返回never的函数必须存在无法达到的终点
function error(message: string): never {
    throw new Error(message);
}

// 推断的返回值类型为never
function fail() {
    return error("Something failed");
}

// 返回never的函数必须存在无法达到的终点
function infiniteLoop(): never {
    while (true) {
    }
}

unkown:

TypeScript 3.0中引入的 unknown 类型也被认为是 top type ,但它更安全。与 any 一样,所有类型都可以分配给unknown。

let uncertain: unknown = 'Hello'!;
uncertain = 12;
uncertain = { hello: () => 'Hello!' };

我们只能将 unknown 类型的变量赋值给 any 和 unknown。

let uncertain: unknown = 'Hello'!;
let notSure: any = uncertain;

它确实在很多方面不同于 any 类型。如果不缩小类型,就无法对 unknown 类型执行任何操作。

function getDog() { return '22' }

const dog: unknown = getDog(); dog.hello(); //Object is of type 'unknown'

unknown 类型要安全得多,因为它迫使我们执行额外的类型检查来对变量执行操作。

crazyyoung1020 commented 2 years ago

any,

  1. 代表任何类型,它是top type,也是bottom type
  2. 它能赋值给任意类型
  3. 任何类型也都能赋值给它
  4. 它不做任何类型检查。

unknown

  1. 代表类型未知,它也是top type
  2. 任何值都能赋值给unknown
  3. unknown只能赋值给unknown和any
  4. unknown在不缩小范围的情况下,是不能执行任何操作的。

never

  1. 是bottom type,表示那些永远不存在的值的类型。
  2. never是任何类型的子类型,可以赋值给任何类型
  3. 除了never类型外,任何类型都不能赋值给never类型,
  4. 无法到达终点的函数,或者报错的函数,返回的是never类型,其实什么也没返回。
674252256 commented 2 years ago

any any 是任意值类型,定义为 any 类型的变量允许被赋值为任意类型。

let myFavoriteNumber: any = 'seven' myFavoriteNumber = 7 变量如果在声明的时候,未指定其类型,那么它会被识别为任意值类型,也就是说声明为 any 类型和写 JS 没啥区别

frllk commented 2 years ago

TS中any与unkonow与never类型都是什么

任意类型,不作任何约束,编译时会跳过对其的类型检查

未知类型,写代码的时候还不知道具体会是怎样的数据类型,是 typescript 3.0 中引入的新类型,与 any 类似,但使用前必须进行断言或守卫

用不存在的类型,常用于表示永不能执行到终点的函数返回值,例如抛出异常或函数中执行无限循环的代码(死循环)的函数返回值类型

zcma11 commented 2 years ago
rachern commented 2 years ago

any

可以是任意类型的变量,不做任何约束,编译时会跳过对其的检查

unknown

表示未知类型,即写代码时还不知道具体情况的类型,所有类型都可以分配给 unknown,unknown类型的变量不允许被any或unknown以外的变量赋值,也不允许执行unknown类型变量的方法

never

永不存在的值的类型,例如总会抛出异常或者无限循环、永不返回的函数返回值类型。变量也可以声明为never类型,任何类型都不能赋值给never类型(除了never本身之外)

partiallove commented 2 years ago

TS中any与unkonow与never类型都是什么 any 任意类型,TS的默认类型。不作任何约束,编译时会跳过对其的类型检查

unknown 未知类型;能被赋值为任何类型,但不能被赋值给除了 any 和 unknown 之外的其他类型 unknown 表示未知类型,是 typescript 3.0 中引入的新类型

never 不存在的类型;可以赋值给任何类型,但是不能被任意类型赋值

jiafei-cat commented 2 years ago

any

any 指的是一个任意类型,它是官方提供的一个选择性绕过静态类型检测的作弊方式。我们可以把任何类型的值赋值给 any 类型的变量,也可以把 any 类型的值赋值给除 never 以外任意类型的变量。

unknown

它主要用来描述类型并不确定的变量, 用法与any差不多,但是与 any 不同的是,unknown 在类型上更安全。比如我们可以将任意类型的值赋值给 unknown,但 unknown 类型的值只能赋值给 unknown 或 any, 所以它属于 top type

never

never 表示永远不会发生值的类型, never 是所有类型的子类型,它可以给所有类型赋值, 所以它属于 bottom type

guoshukun1994 commented 2 years ago

1、any类型的变量可以赋值为任何类型,不作任何约束,未指定类型的变量就默认为any类型,编译时会跳过对其的类型检查,不想使用类型检查时候才会用any,是一个不安全的顶层类型

2、unknown是一个比any更安全的的顶层类型,unkown类型的变量只能赋值给any或unknow类型的变量,如果不缩小范围,就无法对unkown的值进行操作: let a: unknown = 3; let b = 4; let c = a + b; // 对象的类型为'unkown'; 这里是无法直接使用unkown的变量的 // 必须强制做类型转换 let c; if(typeof a == 'number') { c = a + b; }

3、never表示用不存在的值的类型,常用于永不能执行到终点的函数返回值,例如抛异常或无限循环的代码的函数返回值类型,never类型是所有类型的子类型,因此所有函数的返回值都包含never类型,因为每个函数都有可能出现异常情况,任意变量都默认包含never类型,当然也可以显示设置;