-
-
Notifications
You must be signed in to change notification settings - Fork 116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
After P.nullish match, value can still be null #145
Comments
Hey! |
I vaguely remember a Typescript bug in the past couple years about this where fixed it and enabled better narrowing. Is there anything I can do to work around this limitation? Like rewriting my matches hierarchically with otherwise clauses? Or do I just need to repeat some conditions I know to be true? As far as performance are you talking compile time performance? I wonder when compile time performance really becomes an issue and breaks auto-complete in the editor. |
This still doesn't work. According to that link you sent
|
The type of narrowing you get in If your input type is a discriminated union of objects, then narrowing works: type Entity =
| { type: 'user', name: string }
| { type: 'org', id: string };
const f = (entity: Entity) =>
match(entity)
.with({ type: 'user' }, () => 'user!')
.with({ type: 'user' }, () => 'user!')
// ^ ❌ Does not type-check in TS-Pattern v4.1
.with({ type: 'org' }, () => 'org!')
.exhaustive() But if your union is inside a data structure like an array or an object, narrowing between branches doesn't work: type Input = {
entity:
| { type: 'user', name: string }
| { type: 'org', id: string }
};
const f = (input: Input) =>
match(entity)
.with({ entity: { type: 'user' } }, () => 'user!')
.with({ entity: { type: 'user' } }, () => 'user!')
// ^ Does type check even if this is already handled
.with({ entity: { type: 'org' } }, () => 'org!')
.exhaustive() In your particular example I would invert my logic to circumvent this limitation: type Person = {
email: string | null;
};
const getEmail1 = (p: Person) =>
match(p)
.with({ email: P.string }, (i) => i.email.trim())
.otherwise(() => undefined) |
Oh, and yes, I was talking about compile time performance. Deep exclusions can be pretty costly because they tend to generate large union types. I'm a bit conservative to avoid making ts-pattern a footgun in terms of compilation time (which is an important aspect of the developer experience) |
Describe the bug
Awesome library! See the code below. I expect that in the final match condition
email
can't be null anymore but TypeScript thinks it is still possible. So I need to do the safestring?.trim()
operator. This works fine with regular TypeScript expression.Code Sandbox with a minimal reproduction case
https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAbziAhjAxgCwDRwApwC+cAZlBCHAOQwDOAtGGjAKZQB2VAUFzAJ5gW+NrQjs4AXkRc4cFqmAAbAFxxaMKMHYBzOAB847AK6LFAbi6ELXdGPVxtLGAFEFigIyS4ACjCq8ImIAlJIAfDLIaFi+QRGyAHQA7sAwmN5I8ihK-vHGpsC0mES43iESoXBG7AAmLCRaLNWxsgnJqd548SjsfCXAZRXA8ZlK8RqgpSEA9FNyUORQcXDDAB6YKEbqwABuLKXWtuz2ji5uAExevv6B7AMRYMNukhJSeYpwAPyVNXUN1XCqB4jRRjTQgfZcIA
Versions
The text was updated successfully, but these errors were encountered: