typescript
GitHub
  • README
  • Давайте Почнемо
    • Why TypeScript
  • JavaScript
    • Equality
    • References
    • Null vs. Undefined
    • this
    • Closure
    • Number
    • Truthy
  • Future JavaScript Now
    • Classes
      • Classes Emit
    • Arrow Functions
    • Rest Parameters
    • let
    • const
    • Destructuring
    • Spread Operator
    • for...of
    • Iterators
    • Template Strings
    • Promise
    • Generators
    • Async Await
  • Проект / Project
    • Контекст компіляції / Compilation Context
      • tsconfig.json
      • Які файли / Which Files?
    • Простори Оголошень / Declaration Spaces
    • Модулі / Modules
      • File Module Details
      • global.d.ts
    • Namespaces
    • Dynamic Import Expressions
  • Node.js QuickStart
  • Browser QuickStart
  • Library QuickStart
  • TypeScript's Type System
    • JS Migration Guide
    • @types
    • Ambient Declarations
      • Declaration Files
      • Variables
    • Interfaces
    • Enums
    • lib.d.ts
    • Functions
    • Callable
    • Type Assertion
    • Freshness
    • Type Guard
    • Literal Types
    • Readonly
    • Generics
    • Type Inference
    • Type Compatibility
    • Never Type
    • Discriminated Unions
    • Index Signatures
    • Moving Types
    • Exception Handling
    • Mixins
  • JSX
    • React
    • Non React JSX
  • Options
    • noImplicitAny
    • strictNullChecks
  • Errors in TypeScript
    • Interpreting Errors
    • Common Errors
  • NPM
  • Testing
    • Jest
    • Cypress
  • Tools
    • Prettier
    • Husky
    • ESLint
    • Changelog
  • TIPs
    • String Based Enums
    • Nominal Typing
    • Stateful Functions
    • Currying
    • Type Instantiation
    • Lazy Object Literal Initialization
    • Classes are Useful
    • Avoid Export Default
    • Limit Property Setters
    • outFile caution
    • JQuery tips
    • static constructors
    • singleton pattern
    • Function parameters
    • Build Toggles
    • Barrel
    • Create Arrays
    • Typesafe Event Emitter
  • StyleGuide
  • TypeScript Compiler Internals
    • Program
    • AST
      • TIP: Visit Children
      • TIP: SyntaxKind enum
      • Trivia
    • Scanner
    • Parser
      • Parser Functions
    • Binder
      • Binder Functions
      • Binder Declarations
      • Binder Container
      • Binder SymbolTable
      • Binder Error Reporting
    • Checker
      • Checker Diagnostics
      • Checker Error Reporting
    • Emitter
      • Emitter Functions
      • Emitter SourceMaps
    • Contributing
Powered by GitBook
On this page
  • Never
  • Use case: Exhaustive Checks
  • Confusion with void
  • Type inference in never returning functions
Edit on GitHub
  1. TypeScript's Type System

Never Type

PreviousType CompatibilityNextDiscriminated Unions

Last updated 1 year ago

Never

Дизайн мови програмування дійсно має концепцію низького типу, що є natural результатом, щойно ви виконуєте code flow analysis, тому йому потрібно надійно представляти те, що може ніколи не статися.

Тип never використовується в TypeScript для позначення цього bottom Випадки, коли це відбувається природним шляхом:

  • Функція ніколи не повертає керування (наприклад, якщо тіло функції має while(true){})

  • Функція завжди видає помилку (наприклад, у function foo(){throw new Error('Not Implemented')} тип повернення foo - never)

Звичайно, ви також можете використовувати цю анотацію самостійно

let foo: never; // Okay

Однак тільки never може бути значення іншого never.

let foo: never = 123; // Error: Tип number не зпівпадає з типом never

// Okay ця функція повертає `never`
let bar: never = (() => { throw new Error(`Throw my hands in the air like I just don't care`) })();

Чудово Тепер давайте просто перейдемо до його ключового випадку використання :)

Use case: Exhaustive Checks

Ви можете викликати функції never у контексті never.

function foo(x: string | number): boolean {
  if (typeof x === "string") {
    return true;
  } else if (typeof x === "number") {
    return false;
  }

  // Без типу never ми б мали помилку:
   // - Не всі шляхи коду повертають значення (суворі перевірки на нуль)
   // - Або виявлено недоступний код
   // Але оскільки TypeScript розуміє, що функція `fail` повертає `never`
   // Це може дозволити вам викликати його, оскільки ви, можливо, використовуєте його для безпеки під час виконання / вичерпних перевірок.
  return fail("Unexhaustive!");
}

function fail(message: string): never { throw new Error(message); }

Confusion with void

Як тільки хтось скаже вам, що never повертається, коли функція ніколи не виходить витончено, ви інтуїтивно хочете думати про це як про те саме, що void. Однак void є істотою. never є завжди неіснуючим.

Функція, яка повертає нічого, повертає Unit void. Однак функція, яка ніколи не повертає (або завжди викидає), повертає never. void — це те, що можна призначити (без strictNullChecking), але never не можна ніколи призначити нічого іншого, крім never.

Type inference in never returning functions

Для оголошень функцій TypeScript за замовчуванням визначає void, як показано нижче:

// Виявлений тип повернення: void
function failDeclaration(message: string) {
  throw new Error(message);
}

// Виявлений тип повернення: never
const failExpression = function(message: string) {
  throw new Error(message);
};

Звичайно, ви можете виправити це за допомогою явної анотації:

function failDeclaration(message: string): never {
  throw new Error(message);
}

Основною причиною є сумісність зворотного слова з реальним кодом JavaScript:

class Base {
    overrideMe() {
        throw new Error("You forgot to override me!");
    }
}

class Derived extends Base {
    overrideMe() {
        // Code that actually returns here
    }
}

If Base.overrideMe .

Реальний TypeScript може подолати це за допомогою abstract функцій, але цей висновок підтримується для сумісності.

А оскільки never можна призначити лише іншому never, ви також можете використовувати його для compile time вичерпних перевірок. Це описано в розділі .

Youtube: Video lesson on the never type
Egghead: Video lesson on the never type
discriminated union section