diff --git a/packages/language-server/test/plugins/typescript/features/DiagnosticsProvider.test.ts b/packages/language-server/test/plugins/typescript/features/DiagnosticsProvider.test.ts index 107480ee2..a1bda880f 100644 --- a/packages/language-server/test/plugins/typescript/features/DiagnosticsProvider.test.ts +++ b/packages/language-server/test/plugins/typescript/features/DiagnosticsProvider.test.ts @@ -265,4 +265,50 @@ describe('DiagnosticsProvider', () => { assert.deepStrictEqual(diagnostics, []); }); + + it('type-checks actions/transitions/animations', async () => { + const { plugin, document } = setup('diagnostics-directive-types.svelte'); + const diagnostics = await plugin.getDiagnostics(document); + + assert.deepStrictEqual(diagnostics, [ + { + code: 2345, + message: + "Argument of type 'HTMLDivElement' is not assignable to parameter of type 'SVGElement & { getTotalLength(): number; }'.\n " + + "Type 'HTMLDivElement' is missing the following properties from type 'SVGElement': ownerSVGElement, viewportElement, correspondingElement, correspondingUseElement", + range: { + end: { + character: 19, + line: 9 + }, + start: { + character: 19, + line: 9 + } + }, + severity: 1, + source: 'ts', + tags: [] + }, + { + code: 2345, + message: + "Argument of type 'HTMLParagraphElement' is not assignable to parameter of type 'HTMLInputElement'.\n " + + "Type 'HTMLParagraphElement' is missing the following properties from type 'HTMLInputElement': accept, alt, autocomplete, checked, and 48 more.", + range: { + end: { + character: 12, + line: 14 + }, + start: { + character: 12, + line: 14 + } + }, + severity: 1, + source: 'ts', + tags: [] + } + ]); + }); }); diff --git a/packages/language-server/test/plugins/typescript/testfiles/diagnostics-directive-types.svelte b/packages/language-server/test/plugins/typescript/testfiles/diagnostics-directive-types.svelte new file mode 100644 index 000000000..fcf906180 --- /dev/null +++ b/packages/language-server/test/plugins/typescript/testfiles/diagnostics-directive-types.svelte @@ -0,0 +1,16 @@ + + +
+ + +

+ +

+ diff --git a/packages/svelte2tsx/src/htmlxtojsx/index.ts b/packages/svelte2tsx/src/htmlxtojsx/index.ts index 075c78c19..059c903d6 100644 --- a/packages/svelte2tsx/src/htmlxtojsx/index.ts +++ b/packages/svelte2tsx/src/htmlxtojsx/index.ts @@ -90,10 +90,10 @@ export function convertHtmlxToJsx( handleActionDirective(htmlx, str, node, parent); break; case 'Transition': - handleTransitionDirective(htmlx, str, node); + handleTransitionDirective(htmlx, str, node, parent); break; case 'Animation': - handleAnimateDirective(htmlx, str, node); + handleAnimateDirective(htmlx, str, node, parent); break; case 'Attribute': handleAttribute(htmlx, str, node, parent); diff --git a/packages/svelte2tsx/src/htmlxtojsx/nodes/animation-directive.ts b/packages/svelte2tsx/src/htmlxtojsx/nodes/animation-directive.ts index 39039448b..d6f967aed 100644 --- a/packages/svelte2tsx/src/htmlxtojsx/nodes/animation-directive.ts +++ b/packages/svelte2tsx/src/htmlxtojsx/nodes/animation-directive.ts @@ -3,27 +3,34 @@ import { Node } from 'estree-walker'; import { isQuote } from '../utils/node-utils'; /** - * animate:xxx(yyy) ---> {...__sveltets_ensureAnimation(xxx(__sveltets_ElementNode,__sveltets_AnimationMove,(yyy)))} + * animate:xxx(yyy) ---> {...__sveltets_ensureAnimation(xxx(__sveltets_mapElementTag('..'),__sveltets_AnimationMove,(yyy)))} */ -export function handleAnimateDirective(htmlx: string, str: MagicString, attr: Node): void { +export function handleAnimateDirective( + htmlx: string, + str: MagicString, + attr: Node, + parent: Node +): void { str.overwrite( attr.start, htmlx.indexOf(':', attr.start) + 1, '{...__sveltets_ensureAnimation(' ); + const nodeType = `__sveltets_mapElementTag('${parent.name}')`; + if (!attr.expression) { if (animationsThatNeedParam.has(attr.name)) { - str.appendLeft(attr.end, '(__sveltets_ElementNode,__sveltets_AnimationMove,{}))}'); + str.appendLeft(attr.end, `(${nodeType},__sveltets_AnimationMove,{}))}`); } else { - str.appendLeft(attr.end, '(__sveltets_ElementNode,__sveltets_AnimationMove))}'); + str.appendLeft(attr.end, `(${nodeType},__sveltets_AnimationMove))}`); } return; } str.overwrite( htmlx.indexOf(':', attr.start) + 1 + `${attr.name}`.length, attr.expression.start, - '(__sveltets_ElementNode,__sveltets_AnimationMove,(' + `(${nodeType},__sveltets_AnimationMove,(` ); str.appendLeft(attr.expression.end, ')))'); if (isQuote(htmlx[attr.end - 1])) { diff --git a/packages/svelte2tsx/src/htmlxtojsx/nodes/transition-directive.ts b/packages/svelte2tsx/src/htmlxtojsx/nodes/transition-directive.ts index c6ceec688..57a2cbce3 100644 --- a/packages/svelte2tsx/src/htmlxtojsx/nodes/transition-directive.ts +++ b/packages/svelte2tsx/src/htmlxtojsx/nodes/transition-directive.ts @@ -3,9 +3,14 @@ import { Node } from 'estree-walker'; import { isQuote } from '../utils/node-utils'; /** - * transition:xxx(yyy) ---> {...__sveltets_ensureTransition(xxx(__sveltets_ElementNode,(yyy)))} + * transition:xxx(yyy) ---> {...__sveltets_ensureTransition(xxx(__sveltets_mapElementTag('..'),(yyy)))} */ -export function handleTransitionDirective(htmlx: string, str: MagicString, attr: Node): void { +export function handleTransitionDirective( + htmlx: string, + str: MagicString, + attr: Node, + parent: Node +): void { str.overwrite( attr.start, htmlx.indexOf(':', attr.start) + 1, @@ -17,11 +22,13 @@ export function handleTransitionDirective(htmlx: string, str: MagicString, attr: str.remove(local, attr.expression ? attr.expression.start : attr.end); } + const nodeType = `__sveltets_mapElementTag('${parent.name}')`; + if (!attr.expression) { if (transitionsThatNeedParam.has(attr.name)) { - str.appendLeft(attr.end, '(__sveltets_ElementNode,{}))}'); + str.appendLeft(attr.end, `(${nodeType},{}))}`); } else { - str.appendLeft(attr.end, '(__sveltets_ElementNode))}'); + str.appendLeft(attr.end, `(${nodeType}))}`); } return; } @@ -29,7 +36,7 @@ export function handleTransitionDirective(htmlx: string, str: MagicString, attr: str.overwrite( htmlx.indexOf(':', attr.start) + 1 + `${attr.name}`.length, attr.expression.start, - '(__sveltets_ElementNode,(' + `(${nodeType},(` ); str.appendLeft(attr.expression.end, ')))'); if (isQuote(htmlx[attr.end - 1])) { diff --git a/packages/svelte2tsx/svelte-shims.d.ts b/packages/svelte2tsx/svelte-shims.d.ts index 08d3bec86..379aec9e8 100644 --- a/packages/svelte2tsx/svelte-shims.d.ts +++ b/packages/svelte2tsx/svelte-shims.d.ts @@ -98,7 +98,6 @@ type SvelteStore = { subscribe: (run: (value: T) => any, invalidate?: any) => declare var process: NodeJS.Process & { browser: boolean } -declare var __sveltets_ElementNode: Element declare var __sveltets_AnimationMove: { from: DOMRect, to: DOMRect } declare function __sveltets_ensureAnimation(animationCall: SvelteAnimationReturnType): {}; diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/animation-bare/expected.jsx b/packages/svelte2tsx/test/htmlx2jsx/samples/animation-bare/expected.jsx index fcd4b7cb6..750d1be04 100644 --- a/packages/svelte2tsx/test/htmlx2jsx/samples/animation-bare/expected.jsx +++ b/packages/svelte2tsx/test/htmlx2jsx/samples/animation-bare/expected.jsx @@ -1 +1 @@ -<>

Hello

+<>

Hello

diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/animation-params/expected.jsx b/packages/svelte2tsx/test/htmlx2jsx/samples/animation-params/expected.jsx index 106118506..47505c0ad 100644 --- a/packages/svelte2tsx/test/htmlx2jsx/samples/animation-params/expected.jsx +++ b/packages/svelte2tsx/test/htmlx2jsx/samples/animation-params/expected.jsx @@ -1,4 +1,4 @@ -<>

Hello

-

Hello

-

Hello

+<>

Hello

+

Hello

+

Hello

diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/directive-quoted/expected.jsx b/packages/svelte2tsx/test/htmlx2jsx/samples/directive-quoted/expected.jsx index a325c0b49..c625af310 100644 --- a/packages/svelte2tsx/test/htmlx2jsx/samples/directive-quoted/expected.jsx +++ b/packages/svelte2tsx/test/htmlx2jsx/samples/directive-quoted/expected.jsx @@ -1,7 +1,7 @@ <>

console.log("click")}>Hello

{__sveltets_instanceOf(Component).$on('click', test)} - + - + diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/transition-animate-fallbacks/expected.jsx b/packages/svelte2tsx/test/htmlx2jsx/samples/transition-animate-fallbacks/expected.jsx index bd7d81069..6d549948c 100644 --- a/packages/svelte2tsx/test/htmlx2jsx/samples/transition-animate-fallbacks/expected.jsx +++ b/packages/svelte2tsx/test/htmlx2jsx/samples/transition-animate-fallbacks/expected.jsx @@ -1,17 +1,17 @@ <> -

Hello

-

Hello

-

Hello

-

Hello

-

Hello

-

Hello

+

Hello

+

Hello

+

Hello

+

Hello

+

Hello

+

Hello

-

Hello

-

Hello

+

Hello

+

Hello

-

Hello

+

Hello

-

Hello

-

Hello

-

Hello

-

Hello

\ No newline at end of file +

Hello

+

Hello

+

Hello

+

Hello

\ No newline at end of file diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/transition-bare/expected.jsx b/packages/svelte2tsx/test/htmlx2jsx/samples/transition-bare/expected.jsx index 7386f222c..2fa1d6743 100644 --- a/packages/svelte2tsx/test/htmlx2jsx/samples/transition-bare/expected.jsx +++ b/packages/svelte2tsx/test/htmlx2jsx/samples/transition-bare/expected.jsx @@ -1,3 +1,3 @@ -<>

Hello

-

Hello

-

Hello

+<>

Hello

+

Hello

+

Hello

diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/transition-modifiers/expected.jsx b/packages/svelte2tsx/test/htmlx2jsx/samples/transition-modifiers/expected.jsx index e637c7a30..3b5af3f2d 100644 --- a/packages/svelte2tsx/test/htmlx2jsx/samples/transition-modifiers/expected.jsx +++ b/packages/svelte2tsx/test/htmlx2jsx/samples/transition-modifiers/expected.jsx @@ -1,3 +1,3 @@ -<>
+<>
{item}
\ No newline at end of file diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/transition-params/expected.jsx b/packages/svelte2tsx/test/htmlx2jsx/samples/transition-params/expected.jsx index 72c195be0..5fbd1b0dc 100644 --- a/packages/svelte2tsx/test/htmlx2jsx/samples/transition-params/expected.jsx +++ b/packages/svelte2tsx/test/htmlx2jsx/samples/transition-params/expected.jsx @@ -1,5 +1,5 @@ -<>

Hello

-

Hello

-

Hello

-

Hello

-

Hello

+<>

Hello

+

Hello

+

Hello

+

Hello

+

Hello