lit-analyzer
lit-analyzer copied to clipboard
Problem with custom directives (no-incompatible-type-binding)
I have been trying to write a simple custom directive which simplifies some use-cases for ifDefined:
// instead of
html`<input pattern=${ifDefined(isNumber ? "[0-9]*" : undefined)} />`
// i would like to do this
html`<input pattern=${cond(isNumber, "[0-9]*")} />`
Cribbing from ifDefined, I came up with this directive:
const cond = <T>(condition: boolean, value: T) => (condition ? value : nothing)
This directive works just fine at runtime, but the vscode plugin complains:
Type 'Symbol(undefined) | "[0-9]*"' is not assignable to 'string'
So I also tried creating a directive as recommended in the lit docs:
class ConditionalDirective extends Directive {
constructor(partInfo: PartInfo) {
super(partInfo)
if (partInfo.type !== PartType.ATTRIBUTE) {
throw new Error("The `cond` directive must be on attributes")
}
}
render(condition: boolean, value: string) {
return condition ? value : nothing
}
}
// Create the directive function
cond = directive(ConditionalDirective)
But now i get a different error:
You are binding a non-primitive type 'DirectiveResult<{ prototype: any; new(partInfo: ChildPartInfo | AttributePartInfo | ElementPartInfo) => ConditionalDirective; }>'.
This could result in binding the string "[object Object]". Use '.' binding instead?
Again, the directive itself works fine at runtime...
I tried following the advice in the error message but then I get a different error again:
Type 'DirectiveResult<{ prototype: any; new(partInfo: ChildPartInfo | AttributePartInfo | ElementPartInfo) => ConditionalDirective; }>' is not assignable to 'string'
Am I doing something wrong here, or is this a bug with lit-analyzer?
~~Interestingly, the complaints go away if i remove the generics from my basic function directive and make value be any.~~
const cond = (condition: boolean, value: any) => (condition ? value : nothing)
~~Though I don't really want to lose typing. And still the problem persists when extending Directive regardless of how i type the render function~~
Edit: ignore this comment. Of course this works, I'm opting out of type checking with any.
I'm having the same problem and I actually would expect the attribute binding to work all the same. In my case, I have a directive which does translation <mwc-tab label="${translate(item)}">. The result of that directive is a string. Lit is perfectly content updating the attribute from the directive result.
For now it appears that I have to bind translate(item) as any...