-
-
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
There are cases where unwanted patterns match. #228
Comments
Both behaviors are expected. TS-Pattern follows the semantic of corresponding object types:
See: const x: {} = { name: 'a' } // ✅ type-checks.
const y: { name: null | undefined } = {} // ❌ doesn't type-check. |
if the |
You can write custom matchers with P.when: const emptyObject = P.when(
(value: unknown) => value && typeof value === 'object' && Object.keys(value).length === 0
) |
@gvergnaud How about creating "P.empty"? .with(P.empty, () => true) It could be used for more versatile applications by matching when "Array", "object", "Map", "Set" are empty. If this seems like a good idea, I will go ahead and create a pull request. Thank you for reading! |
how about const x:Array<string> | Set<number> | Partial<SomeObject> = {}
match(x)
.with(P.object.empty, ()=>"fallback")
.otherwise(()=>"Meh") would be great to suggest this idea on the separated issue, since this issue's topic has been closed. |
I would like to reopen this to handle the following Typescript cases: type Bar = {
type: "bar";
value: "a" | "b";
};
type Foo = {
type: "foo";
value: "x" | "z";
};
declare const foobar: Bar | Foo;
match(foobar)
.with({ type: "bar", value: "a" }, () => {})
.with({ type: "bar", value: "b" }, () => {})
.with({ type: "bar", value: "x" }, () => {}) // does not make sense
.with({ type: "bar", value: "z" }, () => {}) // does not make sense
.with({ type: "foo", value: "a" }, () => {}) // does not make sense
.with({ type: "foo", value: "b" }, () => {}) // does not make sense
.with({ type: "foo", value: "x" }, () => {})
.with({ type: "foo", value: "z" }, () => {}); This looks like due to the fact that the type This case could be fixed with the following: match(foobar)
.with({ type: "bar" }, ({ value }) =>
match(value)
.with("a", () => {})
.with("b", () => {})
.exhaustive(),
)
.with({ type: "foo" }, ({ value }) =>
match(value)
.with("x", () => {})
.with("z", () => {})
.exhaustive(),
); But this is way more verbose than what it could be. |
@nullndr I guess maybe the topic of this issue was too ambiguous. since this issue thread handles P.object.empty case and runtime behaviors, I'd rather open a new one that fits yours. also here's the code for you, you should try yourself import { match, P } from "ts-pattern";
const x: string = "hello world";
match<string,string>(x)
.with(P.number,()=>"impossible")
.otherwise(()=> "always") the pattern P.number doesn't make sense but it's still a valid pattern, whether it matters on runtime or not. |
@JUSTIVE thank you, I will open a new issue where I will respond to your comment. |
Describe the bug
There are cases where unwanted patterns match.
CASE 1
the expected value: false;
a resultant value: true
CASE 2
the expected value: true;
a resultant value: false
Versions
The text was updated successfully, but these errors were encountered: