microsoft / microsoft/TypeScript

Asynchronous type guards and assertion signatures

Ouverte
#37,681 12 commentaires 205 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

In Discussion Suggestion
Langage dominant
Go
Étoiles
111k
Forks
14.3k
Merge moyen
2 j 4 h
PR mergées (30 j)
132

Description

Search Terms

async, asynchronous, promise, type guards, assertion signatures, asserts

Suggestion

TypeScript currently supports user-defined type guards and assertion signatures.

function isCustomType(value: unknown): value is CustomType {
    // ...
}

function assertIsCustomType(value: unknown): asserts value is CustomType {
    // ...
}

I think it would be great if we could also define custom asynchronous type guards and assertions.

async function isCustomType(value: unknown): Promise<value is CustomType> {
    // ...
}

async function assertIsCustomType(value: unknown): Promise<asserts value is CustomType> {
    // ...
}

Use Cases

This feature would allow to check types and validate data asnychonously. Please look at the examples below.

Examples

Imagine the code like this:

interface User {
    name: string;
}

type Valid<T> = T & {
    readonly $valid: unique symbol;
}

async function createUser(user: User): Promise<void> {
    validateUser(user);
    await saveValidUserToDatabase(user);
}

function validateUser(user: User): asserts user is Valid<User> {
    if (user.name.length < 5) {
        throw new Error('User name must be at least 5 characters long');
    }
}

async function saveValidUserToDatabase(user: Valid<User>): Promise<void> {
    // ...
}

But sometimes, validation is done asynchronously, e.g. on server-side. Currently, you can achieve it this way:

async function createUser(user: User): Promise<void> {
    await validateUser(user);
    await saveValidUserToDatabase(user as Valid<User>);
}

async function validateUser(user: User): Promise<void> {
    // ...
}

But if TypeScript supported asynchronous assertions, you could skip as Valid<User> type assertion and let the TS do the job:

async function createUser(user: User): Promise<void> {
    await validateUser(user);
    await saveValidUserToDatabase(user);
}

async function validateUser(user: User): Promise<asserts user is Valid<User>> {
    // ...
}

Exactly the same issue could be presented for user-defined type guards.

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par examiner la gestion existante par TypeScript des gardes de type définis par l’utilisateur et des signatures d’assertion dans le compilateur et le vérificateur de types. Définissez le comportement des gardes et des assertions asynchrones, notamment la manière dont await affecte le rétrécissement de type, puis ajoutez des tests du compilateur couvrant les signatures basées sur Promise proposées et les types de flux de contrôle qui en résultent.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
typescript
Domaine
compilers
Type d'issue
Fonctionnalité
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
25/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.