microsoft / microsoft/TypeScript
Asynchronous type guards and assertion signatures
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.3k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing TypeScript's existing handling of user-defined type guards and assertion signatures in the compiler and type checker. Define the behavior for asynchronous guards and assertions, including how await affects narrowing, then add compiler tests covering the proposed Promise-based signatures and resulting control-flow types.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100