Skip to content
This repository has been archived by the owner on Dec 5, 2024. It is now read-only.

fix: TypeScript types broken with latest popperjs-core #352

Merged
merged 4 commits into from
Apr 21, 2020
Merged

fix: TypeScript types broken with latest popperjs-core #352

merged 4 commits into from
Apr 21, 2020

Conversation

bengry
Copy link

@bengry bengry commented Apr 14, 2020

Fixes #351

src/Popper.js Outdated Show resolved Hide resolved
@bengry bengry requested a review from atomiks April 14, 2020 22:34
@FezVrasta
Copy link
Member

Thanks for the PR! I have not a lot of experience with TS so I'll wait for @atomiks's go ahead before I proceed to merge it.

@atomiks
Copy link
Collaborator

atomiks commented Apr 15, 2020

Works well with the change. I'd like to have this as a default in core too (typed built-in modifiers, untyped custom) but I don't know how the Flow conversion would handle this.

@FezVrasta
Copy link
Member

Works well with the change. I'd like to have this as a default in core too (typed built-in modifiers, untyped custom) but I don't know how the Flow conversion would handle this.

I'm preparing a PR to update the Flow types of react-popper, and it seems to work just like TS.

@atomiks
Copy link
Collaborator

atomiks commented Apr 15, 2020

My suggestions were because I wasn't inlining the modifiers array lol 🤦 — your change is fine.

How would I type this with the modifiers array assigned to a variable instead of inlined?

Copy link
Author

@bengry bengry left a comment

Choose a reason for hiding this comment

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

My suggestions were because I wasn't inlining the modifiers array lol 🤦 — your change is fine.

How would I type this with the modifiers array assigned to a variable instead of inlined?

const modifiers: Modifier<'offset' | 'arrow' | 'externalModifier'> = [
  { name: 'offset', ...},
  { name: 'arrow', ...},
  { name: 'externalModifier', ... }
];

Alternatively, I suggest changing:

type StrictModifier<Name extends StrictModifierNames> = UnionWhere<PopperJS.StrictModifiers, { name?: Name }>;
type StrictModifier<Name extends StrictModifierNames = StrictModifierNames> = UnionWhere<PopperJS.StrictModifiers, { name?: Name }>;

So now you don't have to specify the modifiers in the type up-front, if you only need strict ones:

const modifiers: StrictModifier[] = [
  { name: 'offset', ...},
  { name: 'arrow', ...},
];

Since I think most users only use the strict modifiers anyway, this should be fine IMO.

Of course, you'd need to either export the relevant types, or get them through a generic PropsOf<T> type somehow (example for such a type in emotion).

Let me know if you'd like me to make these changes to the PR before you merge it.

@atomiks
Copy link
Collaborator

atomiks commented Apr 15, 2020

Is it possible to type custom modifiers with this? I'd say it's an important feature

@bengry
Copy link
Author

bengry commented Apr 15, 2020

Is it possible to type custom modifiers with this? I'd say it's an important feature

Sure you can:

const modifiers: (StrictModifier | Modifier<'my-modifier'>)[] = [
  {
    name: 'offset',
    options: {},
  },
  {
    name: 'my-modifier',
    options: {
      someProperty: 'foo',
    },
  },
];

Unfortunately you can't omit the my-modifier in line 1 here (and use string instead of example) since then TS will collapse the two types to a union of all modifiers, and you lose type-safety for strict modifiers - so this will compile, even though it shouldn't (when used inside of an array typed as (StrictModifier | Modifier<string>)[]):

{
  name: 'offset'
  options: {
    adaptive: true,
  },
}

I usually prefer inline types for this reason, TypeScript is much more powerful when you let it infer types than when you explicitly tell the compiler what you want.

Maybe there's a workaround here that I'm missing (apart from creating two arrays - const strictModifiers: StrictModifier[] = [ ... ] and const otherModifiers: Modifier<string>[] = [ ... ] and then merging them later: [...strictModifiers, ...otherModifiers]).

@atomiks
Copy link
Collaborator

atomiks commented Apr 15, 2020

I mean type custom modifers' options like the strict ones (inlined or not)

@bengry
Copy link
Author

bengry commented Apr 15, 2020

I mean type custom modifiers' options like the strict ones (inlined or not)

You can type them like that, they should be able to pass just fine to the modifiers prop/option. Are you having an issue with such a case?

image
Usually MyModifier would come from an external library I suppose?

@atomiks
Copy link
Collaborator

atomiks commented Apr 16, 2020

Seems good now ✅

@bengry
Copy link
Author

bengry commented Apr 16, 2020

@atomiks great, thanks! :)
@FezVrasta can we get this merged and released soon-ish please?

@l0gicgate
Copy link

When will this be merged?

@FezVrasta FezVrasta changed the title Fix TypeScript types broken with latest popperjs-core fix: TypeScript types broken with latest popperjs-core Apr 21, 2020
@FezVrasta FezVrasta merged commit e27b1f6 into floating-ui:master Apr 21, 2020
@evadecker
Copy link

Hi! Thanks for fixing and merging this, was just about to report the issue. Do you know when this fix will be released on NPM?

berekuk added a commit to KochergaClub/core that referenced this pull request Jul 19, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TypeScript types broken with latest version of popper-core
5 participants