microsoft / microsoft/TypeScript

Asynchronous type guards and assertion signatures

Offen
#37,681 12 Kommentare 205 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

In Discussion Suggestion
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.3k
Ø Merge
2 T. 4 Std.
Gemergte PRs (30 T.)
132

Beschreibung

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.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne damit, TypeScripts bestehende Behandlung von benutzerdefinierten Typwächtern und Assertion-Signaturen im Compiler und Type Checker zu überprüfen. Definiere das Verhalten asynchroner Wächter und Assertionen, einschließlich der Auswirkungen von await auf die Eingrenzung, und füge anschließend Compiler-Tests hinzu, die die vorgeschlagenen Promise-basierten Signaturen und die daraus resultierenden Control-Flow-Typen abdecken.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
typescript
Bereich
compilers
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
25/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.