Skip to content

Commit

Permalink
(fix) silence duplicate props warning for window/body (#1656)
Browse files Browse the repository at this point in the history
  • Loading branch information
dummdidumm committed Sep 22, 2022
1 parent ab19d05 commit a6a6ee7
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 14 deletions.
27 changes: 13 additions & 14 deletions packages/language-server/src/plugins/typescript/svelte-ast-utils.ts
Expand Up @@ -5,6 +5,17 @@ export interface SvelteNode {
parent?: SvelteNode;
}

type HTMLLike = 'Element' | 'InlineComponent' | 'Body' | 'Window';

function matchesOnly(type: string | undefined, only?: 'Element' | 'InlineComponent'): boolean {
return (
!only ||
// We hide the detail that body/window are also like elements in the context of this usage
(only === 'Element' && ['Element', 'Body', 'Window'].includes(type as HTMLLike)) ||
(only === 'InlineComponent' && type === 'InlineComponent')
);
}

/**
* Returns when given node represents an HTML Attribute.
* Example: The `class` in `<div class=".."`.
Expand All @@ -14,19 +25,7 @@ export function isAttributeName(
node: SvelteNode | null | undefined,
only?: 'Element' | 'InlineComponent'
): boolean {
return !!node && node.type === 'Attribute' && (!only || node.parent?.type === only);
}

/**
* Returns when given node represents an HTML element.
* Example: The `div` in `<div class=".."`.
* Note: This method returns `false` for shorthands like `<div {foo}`.
*/
export function isHTMLElement(
node: SvelteNode | null | undefined,
only?: 'Element' | 'InlineComponent'
): boolean {
return !!node && node.type === 'Attribute' && (!only || node.parent?.type === only);
return !!node && node.type === 'Attribute' && matchesOnly(node.parent?.type, only);
}

/**
Expand Down Expand Up @@ -59,5 +58,5 @@ export function isEventHandler(
node: SvelteNode | null | undefined,
only?: 'Element' | 'InlineComponent'
) {
return !!node && node.type === 'EventHandler' && (!only || node.parent?.type === only);
return !!node && node.type === 'EventHandler' && matchesOnly(node.parent?.type, only);
}
@@ -0,0 +1,24 @@
[
{
"range": {
"start": { "line": 10, "character": 5 },
"end": { "line": 10, "character": 11 }
},
"severity": 1,
"source": "ts",
"message": "Type '{ onwat: () => string; }' is not assignable to type 'HTMLProps<HTMLDivElement>'.\n Property 'onwat' does not exist on type 'HTMLProps<HTMLDivElement>'.",
"code": 2322,
"tags": []
},
{
"range": {
"start": { "line": 11, "character": 22 },
"end": { "line": 11, "character": 25 }
},
"severity": 1,
"source": "ts",
"message": "Property 'asd' does not exist on type 'MouseEvent & { currentTarget: EventTarget & HTMLDivElement; }'.",
"code": 2339,
"tags": []
}
]
@@ -0,0 +1,24 @@
[
{
"range": {
"start": { "line": 10, "character": 8 },
"end": { "line": 10, "character": 21 }
},
"severity": 1,
"source": "ts",
"message": "Argument of type '{ \"on:wat\": () => string; }' is not assignable to parameter of type 'HTMLProps<\"div\", HTMLAttributes<any>>'.\n Object literal may only specify known properties, and '\"on:wat\"' does not exist in type 'HTMLProps<\"div\", HTMLAttributes<any>>'.",
"code": 2345,
"tags": []
},
{
"range": {
"start": { "line": 11, "character": 22 },
"end": { "line": 11, "character": 25 }
},
"severity": 1,
"source": "ts",
"message": "Property 'asd' does not exist on type 'MouseEvent & { currentTarget: EventTarget & HTMLDivElement; }'.",
"code": 2339,
"tags": []
}
]
@@ -0,0 +1,12 @@
<script lang="ts">
</script>

<!-- valid -->
<div on:click={() => ''} />
<div on:click={() => ''} on:click={() => ''} />
<svelte:window on:click={() => ''} on:click={() => ''} />
<svelte:body on:click={() => ''} on:click={() => ''} />

<!-- invalid -->
<div on:wat={() => ''} />
<div on:click={e => e.asd} />

0 comments on commit a6a6ee7

Please sign in to comment.