GithubHelp home page GithubHelp logo

Comments (8)

JUSTIVE avatar JUSTIVE commented on June 8, 2024 2

if the {} matches all object types, then is there any way to match {} (an empty object) exactly?

from ts-pattern.

JUSTIVE avatar JUSTIVE commented on June 8, 2024 2

how about P.object.empty for a more precise expression? A P.empty could be ambiguous in some situations:

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.

from ts-pattern.

gvergnaud avatar gvergnaud commented on June 8, 2024 1

Both behaviors are expected. TS-Pattern follows the semantic of corresponding object types:

  • The {} type contains every object, including { name: string }
  • The { name: null | undefined } has a required property name, so {} isn't assignable to it.

See:

const x: {} = { name: 'a' } // ✅ type-checks.
const y: { name: null | undefined } = {} // ❌ doesn't type-check.

from ts-pattern.

gvergnaud avatar gvergnaud commented on June 8, 2024 1

You can write custom matchers with P.when:

const emptyObject = P.when(
  (value: unknown) => value && typeof value === 'object' && Object.keys(value).length === 0
)

from ts-pattern.

nullndr avatar nullndr commented on June 8, 2024 1

@JUSTIVE thank you, I will open a new issue where I will respond to your comment.

from ts-pattern.

gitsunmin avatar gitsunmin commented on June 8, 2024

@gvergnaud
I've read the comments you've posted, and I have a suggestion I'd like to make.

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!

from ts-pattern.

nullndr avatar nullndr commented on June 8, 2024

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 KnownPattern simply relies on the key's type used, creating an union, without having knowledge of the full pattern itself.

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.

from ts-pattern.

JUSTIVE avatar JUSTIVE commented on June 8, 2024

@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.
By the way, I'm not sure it's right to filter out patterns that don't make sense.
as shown below:

image

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.

from ts-pattern.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.