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

Another no-incompatible-type-binding issue, can't assign string[] to Iterable<string> #381

Open
tjcrowder opened this issue Jan 20, 2025 · 3 comments

Comments

@tjcrowder
Copy link

tjcrowder commented Jan 20, 2025

Thanks for lit-analyzer/lit-plugin!

I'm getting the no-incompatible-type-binding error with a simple case of assigning a string[] to a property of type Iterable<string> | undefined. Component:

@customElement("simple-list")
export class SimpleListElement extends LitElement {
    @property({ attribute: false })
    items?: Iterable<string>;

    render() {
        return html`
            <ul>
                ${map(this.items, (item) => html`<li>${item}</li>`)}
            </ul>
        `;
    }
}

This usage fails:

const exampleItems = ["This", "That", "The other"];
const r = html`<simple-list .items=${exampleItems}></simple-list> `;

Error:

Type 'string[]' is not assignable to 'Iterable<string, any, any> | undefined'
lit-plugin(no-incompatible-type-binding)(2304)

Clearly, string[] is assignable to Iterable<string> | undefined. (I try never to use an array type for properties/parameters/etc. where an Iterable will do.)

Changing the type on items to string[] (or its other name, Array<string>) makes the error go away, but unnecessarily limits the property.

Some related issues, there seems to be a fundamental issue with the type checking:
#149, #154, #163, #356

TIA!

@tjcrowder
Copy link
Author

Well I've been down quite the rabbit hole today. 🙂 Seeing that lit-analyzer was using ts-simple-type which hasn't been updated in several years, and that in the meantime TypeScript's compiler API has made the isTypeAssignableTo API function public, I looked into whether I could possibly offer a PR using that function. But it looks like ts-simple-type does try to use isTypeAssignableTo if it's on the checker (even though it wasn't public then; they made it public because lots of people wanted to use it). And my initial naive isolated experiments with isTypeAssignableTo indicate that when dealing with things like Iterable<string>, just calling the function isn't sufficient (it said Iterable<string> is assignable to string[], which isn't true; the converse is true [and it allowed that], but not that way around). Other checks worked (allows assigning string[] to string[] | number[] and (string | number)[], but not the converse, as expected), but Iterable<string> appears to require a further check of some kind, so it'll take non-naive effort. I probably won't have bandwidth to do it, though I'd like to (but I have to get to work now).

@tjcrowder
Copy link
Author

Sigh and now -- as soon as I post the above -- my isolated experiment is correctly disallowing assigning Iterable<string> to string[]. Not enough coffee earlier? Don't know. I'll come back to it.

@tjcrowder
Copy link
Author

I've been further into this, and even though ts-simple-type does use TypeScript's isTypeAssignableTo in some cases, it doesn't in this case because both of the types it's being asked to test are SimpleType instances, not Type instances. I've had a good look at the lit-analyzer code but unfortunately I haven't had enough time to properly assess the scope of always using a TypeScript TypeChecker. I suspect it's possible although AFAICT TypeScript still doesn't provide a clean and clear way to create a type from a string (it's possible to work around it, but it's ugly and probably slow). I doubt it's easy.

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

No branches or pull requests

1 participant