runem / lit-analyzer

Monorepository for tools that analyze lit-html templates
MIT License
319 stars 38 forks source link

lit-plugin(no-complex-attribute-binding) when property has a converter #123

Open bennypowers opened 4 years ago

bennypowers commented 4 years ago

Hello!

My intended API is

// either
html`<trigger-mutation refetch-queries="OneQuery,AnotherQuery"></trigger-mutation>`
// or
html`<trigger-mutation .refetchQueries="${['OneQuery', 'AnotherQuery']}"></trigger-mutation>`

As such, I've defined refetchQueries as:

class TriggerMutation extends ApolloMutation {
  @property({ attribute: 'refetch-queries', converter: {
    fromAttribute(string: string): string[] {
      return !string ? undefined : string.split(',').map(x => x.trim()).filter(Boolean);
    },
    toAttribute(value: string[]): string {
      return Array.isArray(value) ? value.join(',') : null;
    },
  } })
  refetchQueries: string[];
}

Only to get this error:

You are assigning the primitive '"OneQuery,AnotherQuery"' to a non-primitive type 'string[]'. Use '.' binding instead?lit-plugin(no-complex-attribute-binding)(2)

As converter is intended to cast strings, perhaps this rule should be amended to allow ignoring properties with a converter or with type: Array or type: Object.

43081j commented 4 years ago

I can have a go at this, though question for @runem: do we keep any context around the original property definition? by the time our visitors get the assignment, the target will just be a typed property will it not? i.e. it won't have any knowledge by that point of if there's a converter or not.

my suggested fix is:

runem commented 4 years ago

@bennypowers Thanks for reporting this issue :-)

Here are my thoughts:

@43081j Thanks for offering your help! I see that you already found out how to check for custom converters :+1:

pmcelhaney commented 3 years ago

I've run into the same problem. I'm curious why this code would ever be flagged.

html`<trigger-mutation refetch-queries="OneQuery,AnotherQuery"></trigger-mutation>`

The description is "Disallow attribute bindings with a complex type." I don't see any complex type there. I see an attribute bound to a string, which is the only type allowed in this context. An attribute value is always a string (a DOMString to be precise). We don't need to know anything about the implementation of the custom element to know that.

In contrast, this should probably be flagged by the rule:

html`<trigger-mutation refetch-queries="${['OneQuery', 'AnotherQuery']}"></trigger-mutation>`

because you most likely meant this instead:

html`<trigger-mutation .refetchQueries="${['OneQuery', 'AnotherQuery']}"></trigger-mutation>`
43081j commented 3 years ago

Been a while but iirc it means you have passed a string value (because you used an attribute binding) to a complex property (it is complex because in the class, it isn't a string).

Maybe it could be worded better

Totally forgot about this and the related PR I opened! I'll see if I can catch myself up on it again some time soon

klasjersevi commented 11 months ago

I just bumped into this problem. Any updates on this issue?

h4de5 commented 10 months ago

looking forward for a solution too.