阅读链接: TypeScript 中的 never unknown
    【TypeScript】 never unknown

    1. TypeScript 2.0 引入了 never,TypeScript 3.0 引入了 unknown
    2. TypeScript 中的 top type、bottom type

    Top type 被称为通用父类型,如 any 、unknown;Bottom type 代表没有值的类型,或者空类型
    image.png

    1. unknown 和 any

    unknown 表示万物

    1. /*
    2. * any 执行代码时很容易出错,unknown 结合类型守卫确保在上游数据结构不确定时,让代码正确执行
    3. */
    4. function format1(value: any){
    5. value.toFixed(2) // 不会飘红
    6. }
    7. function format2(value: unknown) {
    8. value.toFixed(2) // 代码会飘红,阻止这样做
    9. // 需要收窄类型范围
    10. 1. 类型断言
    11. (value as number).toFixed(2) // 代码不飘红,但执行可能错误
    12. 2. 类型守卫
    13. if (typeof value === 'number') {
    14. value.toFixed(2) // 代码不飘红,且正确执行
    15. }
    16. 3. 类型断言函数,抛出错误
    17. assertIsNumber(value) // 不飘红,正确执行
    18. value.toFixed(2)
    19. }
    20. function assertIsNumber(arg: unknown): asserts arg is Number {
    21. if (!(arg instanceof Number)) {
    22. throw new TypeError('xx' + arg)
    23. }
    24. }
    1. never 表示空类型,值永远不存在的类型

    值不存在的两种情况:

    • 函数执行时抛出异常,函数没有返回值
    • 函数中执行无限循环代码,函数没有返回值 ```typescript // 异常 function err(msg: string): never { // OK throw new Error(msg); }

    // 死循环 function loopForever(): never { // OK while (true) {}; }

    1. never typescript 唯一一个 bottom type,能够表示任何类型的子类型,所以能够赋值给任何类型。never 除了自身外,没有任何值可以赋值给它,但它可以赋值给任何值<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/399967/1653879991421-6bbd8080-5164-4f65-9f32-8f14f5d8363c.png#clientId=ua01e2f01-cdac-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=324&id=ubfe5d457&margin=%5Bobject%20Object%5D&name=image.png&originHeight=648&originWidth=1080&originalType=binary&ratio=1&rotation=0&showTitle=false&size=78571&status=done&style=none&taskId=u71fe01c5-8aa6-4c29-8ffb-f1c6676be64&title=&width=540)
    2. ```typescript
    3. declare const n: never;
    4. let a: null = n; ✅
    5. let b: undefined = n; ✅
    6. let nv: never;
    7. nv = a; ❌
    8. nv = b; ❌

    由上: bottom type 是独一无二的,它唯一地描述了函数无返回值的情况
    never 的使用场景:

    • Unreachable code 检查 ```typescript function listen(): never { //… } listen() // 当 listen 函数给出返回值 never 类型时,编译器会给出如下不可达提示 console.log(‘11’) // Unreachable code detected.ts(7027)

    // 例子二 帮助收窄类型 function throwError() { throw new Error(); }

    function firstChar(msg: string | undefined) { if (msg === undefined) throwError(); // 如果 throwError 没有给出返回类型 never,则编译器认为下边的代码在任意情况可达,编译器误认为 msg 的类型为 string | undefined,加上类型 never 则 msg 认为是 string let chr = msg.charAt(1) // Object is possibly ‘undefined’. }

    1. - 类型运算
    2. ```typescript
    3. // 收窄联合类型,从 T 中排除 null undefined
    4. type NullOrUndefined = null | undefined
    5. type NonNullable<T> = T extends NullOrUndefined ? never : T
    • Exhaustive Check:为复合类型创造编译提示(穷尽检查) ```typescript interface Foo { type: ‘foo’ }

    interface Bar { type: ‘bar’ }

    type All = Foo | Bar | Baz;

    function handleValue(val: All) { switch (val.type) { case’foo’: // val 此时是 Foo break; case’bar’: // val 此时是 Bar break; default: // val 此时是 Baz // ❌ Type ‘Baz’ is not assignable to type ‘never’.(2322) const exhaustiveCheck: never = val; break; } } ```