Created
January 25, 2025 10:44
-
-
Save magoz/ea431d0422accb372daa946fe12d8b34 to your computer and use it in GitHub Desktop.
Narrowing Error and Result
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type User = { | |
id: string | |
name: string | |
} | |
// This works because error is an Error. Internally, object is a non-primitive type (it's a class instance), | |
// and TypeScript can use it as a reliable discriminant. | |
// When you check if (r.error), TypeScript knows that an Error object is always truthy, | |
// making it a reliable way to narrow the type. | |
const narrowWithError = (id?: string) => { | |
if (!id) return { error: new Error('error message') } | |
return { result: { id, name: 'user name' } } | |
} | |
const runNarrowWithError = () => { | |
const r = narrowWithError('123') | |
if (r.error) { | |
return | |
} | |
console.log(r.result) // result is User | |
} | |
// This doesn't work as well because a string can be empty ('') which is falsy, | |
// so TypeScript can't use it as a reliable discriminant. | |
// When you check if (r.error), TypeScript can't be 100% sure about the type narrowing because strings can be falsy. | |
const narrowWithString = (id?: string) => { | |
if (!id) return { error: 'error message' } | |
return { result: { id, name: 'user name' } } | |
} | |
const runNarrowWithString = () => { | |
const r = narrowWithString('123') | |
if (r.error) { | |
return | |
} | |
console.log(r.result) // result is User | undefined | |
// Explicit type checking allows TypeScript to narrow the type correctly | |
const r2 = narrowWithString('123') | |
if (r2.error !== undefined) { | |
return | |
} | |
console.log(r2.result) // result is User | |
// Destructuring works too! | |
const { error, result } = narrowWithString('123') | |
if (error !== undefined) { | |
return | |
} | |
console.log(result) // result is User | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment