Skip to content
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

👍 Add isIncludeIn #32

Closed
wants to merge 1 commit into from
Closed

👍 Add isIncludeIn #32

wants to merge 1 commit into from

Conversation

Milly
Copy link
Collaborator

@Milly Milly commented Jul 25, 2023

A convenience function that defines a union type enum.

@lambdalisue
Copy link
Member

Blocked by #33

Copy link
Member

@lambdalisue lambdalisue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the advantage of this isIncludeIn function over isOneOf? It seems the function is useless for object or array while it compoare values with SameValueZero algorithm?

@Milly
Copy link
Collaborator Author

Milly commented Jul 25, 2023

The purpose of this function is to check the type of the Union type Enum that consists mainly of strings.

import is, { type Predicate } from "./is.ts";

export type Enum = "foo" | "bar" | "baz";

// Implement as `IncludeIn`
export const isEnum: Predicate<Enum> = is.IncludeIn(
  ["foo", "bar", "baz"] as const,
);

const value: unknown = "foo";
if (isEnum(value)) {
  const _: Enum = value;
}

// Same thing as `OneOf`
export const isEnumByOneOf: Predicate<Enum> = is.OneOf([
  (x: unknown): x is "foo" => x === "foo",
  (x: unknown): x is "bar" => x === "bar",
  (x: unknown): x is "baz" => x === "baz",
]);

// Same thing without library
export const isEnumByJS: Predicate<Enum> = (x: unknown): x is Enum =>
  ["foo", "bar", "baz"].includes(x as string);

@lambdalisue
Copy link
Member

The purpose of this function is to check the type of the Union type Enum that consists mainly of strings.

The following are some of the disadvantages of isIncludeIn.

  1. It ends with "In" instead of "Of" even though it is a Predicate factory function and that's not consistent with existing functions
  2. It does not behave as expected even though it is possible to specify an Object or Array to items.

Therefore, if you are assuming a Union type Enum, one of the following would be better

  1. Create a function for literal judgment like isLiteralOf<T extends string>(literal: T): Predicate<T> and use it with isOneOf (I personally think this is more consistent with the usage of existing functions)
  2. Create a isString derived Union type Enum function like isStringOf<T extends string[]>(items: T): Predicate<T[number]>.

What do you think?

@Milly
Copy link
Collaborator Author

Milly commented Jul 25, 2023

I want it to be a function that takes an array of literal values.
How about the following?

type Primitive =
  | null
  | undefined
  | string
  | number
  | boolean
  | symbol
  | bigint;

function isLiteralOf<T extends readonly Primitive[]>(literals: T): Predicate<T[number]>;

@lambdalisue
Copy link
Member

lambdalisue commented Jul 25, 2023

Does TypeScript support a literal type of null, undefined, symbol, or bigint? If not, T must not contain those I think.

@Milly
Copy link
Collaborator Author

Milly commented Jul 25, 2023

Typescript (and JavaScript, of course) treats null, undefined, symbol, or bigint as primitives.
Unfortunately the standard library does not define a union type like Primitive.

@lambdalisue
Copy link
Member

lambdalisue commented Jul 25, 2023

Typescript (and JavaScript, of course) treats null, undefined, symbol, or bigint as primitives.

Yes but my wondering is a bit different. I'm wondering that what about "literal types" in TypeScript.

https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types

As long as we define isLiteralOf or whatever, we'd like to follow TypeScript convension.

@Milly
Copy link
Collaborator Author

Milly commented Jul 25, 2023

How about naming it isPrimitiveOf()?

@lambdalisue
Copy link
Member

lambdalisue commented Jul 26, 2023

How about naming it isPrimitiveOf()?

It makes sense but does it useful? What that function is for? (I'm asking because I want to keep a function responsibilities as small as possible.)

@lambdalisue
Copy link
Member

I prefer isLiteralOf over isPrimitiveOf because I think "string" or 100 is literal type but primitive type.

CleanShot 2023-07-26 at 15 49 29

But I'm not sure if we should call null and undefined is "literal type"...

@lambdalisue
Copy link
Member

Close due to #35

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants