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

Libraries using @prismicio/types with different versions results in type errors #16

Closed
angeloashmore opened this issue Oct 14, 2021 · 4 comments · Fixed by #18
Closed
Labels
bug Something isn't working

Comments

@angeloashmore
Copy link
Member

Versions

  • @prismicio/types: v0.1.15
  • node: v14.17.0

Reproduction

This is difficult to reproduce so I'll share a general proof.

enum A {
	foo = "foo",
}

enum B {
	foo = "foo",
}

const val: A.foo = B.foo;
// [tsserver 2322] [E] Type 'B' is not assignable to type 'A'.

Despite A.foo and B.foo having equivalent literal values, TypeScript treats them as distinct types.

In the types library, this scenario happens when dependent libraries resolve different @prismicio/types installations. More specifically, when the RichTextNodeType enum exists in more than one location, TypeScript sees them as incompatible.

The following node_modules structure produces this:

  • node_modules/@prismicio/types
  • node_modules/@prismicio/mock/node_modules/@prismicio/types

This occurs when packages resolve to different versions of @prismicio/types, thus requiring dependent packages to install their own version of @prismicio/types.

Steps to reproduce

I'm having trouble finding reproducible steps that cause this, but indeed it happens:

image

What is expected?

Type errors do not occur when multiple versions of @prismicio/types are installed. Type errors due to structural differences between versions are expected.

What is actually happening?

Multiple versions cause enum incompatibilities. See the above example errors.

@angeloashmore angeloashmore added the bug Something isn't working label Oct 14, 2021
@angeloashmore
Copy link
Member Author

angeloashmore commented Oct 14, 2021

One solution is to not use an enum. Enum-like types exist, such as a const object.

Remember that most enums, including RichTextNodeType, are exported as a public API for libraries like @prismicio/helpers. Thus, replacing it with a string union is not ideal as that would require users to type the strings by hand.

Before:

declare const enum RichTextNodeType {
  heading1 = "heading1",
  heading2 = "heading2",
  heading3 = "heading3",
  heading4 = "heading4",
  heading5 = "heading5",
  heading6 = "heading6",
  paragraph = "paragraph",
  preformatted = "preformatted",
  strong = "strong",
  em = "em",
  listItem = "list-item",
  oListItem = "o-list-item",
  list = "group-list-item",
  oList = "group-o-list-item",
  image = "image",
  embed = "embed",
  hyperlink = "hyperlink",
  label = "label",
  span = "span",
}

After:

declare type RichTextNodeType = {
  heading1: "heading1";
  heading2: "heading2";
  heading3: "heading3";
  heading4: "heading4";
  heading5: "heading5";
  heading6: "heading6";
  paragraph: "paragraph";
  preformatted: "preformatted";
  strong: "strong";
  em: "em";
  listItem: "list-item";
  oListItem: "o-list-item";
  list: "group-list-item";
  oList: "group-o-list-item";
  image: "image";
  embed: "embed";
  hyperlink: "hyperlink";
  label: "label";
  span: "span";
};

This resolves the type error shown in the first comment:

const A = {
	foo: "foo",
} as const;

const B = {
	foo: "foo",
} as const;

const val: typeof A["foo"] = B.foo;

The ergonomics of this example need to be improved, but it shows two different types with identical values are compatible.

@lihbr
Copy link
Member

lihbr commented Oct 21, 2021

I like the above, tricky one indeed as we cannot ensure that same version of types is being installed for everyone.

@angeloashmore
Copy link
Member Author

Yeah, not using an enum is not ideal but I think using an object like above is the next best option. On the up side, it might take up less bytes than the generated enum output.

Are you good moving forward with this change?

@lihbr
Copy link
Member

lihbr commented Oct 22, 2021

Yup! Will work on that this afternoon~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants