Skip to content

Commit

Permalink
(feat) enable actions to enhance typings on applied element (#1553)
Browse files Browse the repository at this point in the history
#1243
#431

This assumes we also enhance the typing of the action type in Svelte core so they match
  • Loading branch information
dummdidumm committed Aug 26, 2022
1 parent 7d6d2e6 commit 9e1f5d3
Show file tree
Hide file tree
Showing 15 changed files with 249 additions and 92 deletions.
@@ -0,0 +1,68 @@
[
{
"range": {
"start": { "line": 22, "character": 9 },
"end": { "line": 22, "character": 14 }
},
"severity": 1,
"source": "ts",
"message": "Argument of type '{ $$_attributes: { foo: string; 'on:bar': (e: CustomEvent<boolean>) => void; }; }' is not assignable to parameter of type 'SvelteActionReturnType'.",
"code": 2345,
"tags": []
},
{
"range": {
"start": { "line": 22, "character": 16 },
"end": { "line": 22, "character": 19 }
},
"severity": 1,
"source": "ts",
"message": "Type '{ foo: string; onbar: (e: CustomEvent<boolean>) => void; }' is not assignable to type 'HTMLProps<HTMLDivElement>'.\n Property 'foo' does not exist on type 'HTMLProps<HTMLDivElement>'.",
"code": 2322,
"tags": []
},
{
"range": {
"start": { "line": 25, "character": 9 },
"end": { "line": 25, "character": 14 }
},
"severity": 1,
"source": "ts",
"message": "Argument of type '{ $$_attributes: { foo: string; 'on:bar': (e: CustomEvent<boolean>) => void; }; }' is not assignable to parameter of type 'SvelteActionReturnType'.",
"code": 2345,
"tags": []
},
{
"range": {
"start": { "line": 25, "character": 16 },
"end": { "line": 25, "character": 19 }
},
"severity": 1,
"source": "ts",
"message": "Type '{ foo: number; onbar: (e: CustomEvent<boolean>) => void; }' is not assignable to type 'HTMLProps<HTMLDivElement>'.\n Property 'foo' does not exist on type 'HTMLProps<HTMLDivElement>'.",
"code": 2322,
"tags": []
},
{
"range": {
"start": { "line": 26, "character": 9 },
"end": { "line": 26, "character": 14 }
},
"severity": 1,
"source": "ts",
"message": "Argument of type '{ $$_attributes: { foo: string; 'on:bar': (e: CustomEvent<boolean>) => void; }; }' is not assignable to parameter of type 'SvelteActionReturnType'.",
"code": 2345,
"tags": []
},
{
"range": {
"start": { "line": 26, "character": 16 },
"end": { "line": 26, "character": 19 }
},
"severity": 1,
"source": "ts",
"message": "Type '{ foo: string; onbar: (e: CustomEvent<string>) => void; }' is not assignable to type 'HTMLProps<HTMLDivElement>'.\n Property 'foo' does not exist on type 'HTMLProps<HTMLDivElement>'.",
"code": 2322,
"tags": []
}
]
@@ -0,0 +1,24 @@
[
{
"range": {
"start": { "line": 25, "character": 16 },
"end": { "line": 25, "character": 19 }
},
"severity": 1,
"source": "ts",
"message": "Type 'number' is not assignable to type 'string'.",
"code": 2322,
"tags": []
},
{
"range": {
"start": { "line": 26, "character": 31 },
"end": { "line": 26, "character": 34 }
},
"severity": 1,
"source": "ts",
"message": "Type '(e: CustomEvent<string>) => void' is not assignable to type '(e: CustomEvent<boolean>) => void'.\n Types of parameters 'e' and 'e' are incompatible.\n Type 'CustomEvent<boolean>' is not assignable to type 'CustomEvent<string>'.\n Type 'boolean' is not assignable to type 'string'.",
"code": 2322,
"tags": []
}
]
@@ -0,0 +1,27 @@
<script lang="ts">
function action(node: any) {
node;
return {
// TODO: replace this with the Svelte interface generic once it lands in Svelte; this fails for the old transformation
$$_attributes: {
foo: 'string',
'on:bar': (e: CustomEvent<boolean>) => {e;}
}
}
}
function onBar(e: CustomEvent<boolean>) {
e;
}
function onWrongBar(e: CustomEvent<string>) {
e;
}
</script>

<!-- valid for new transformation -->
<div use:action foo="valid" on:bar={onBar} />

<!-- invalid -->
<div use:action foo={1} on:bar={onBar} />
<div use:action foo="valid" on:bar={onWrongBar} />
2 changes: 1 addition & 1 deletion packages/svelte2tsx/src/htmlxtojsx_v2/index.ts
Expand Up @@ -132,7 +132,7 @@ export function convertHtmlxToJsx(
handleStyleDirective(str, node as StyleDirective, element as Element);
break;
case 'Action':
handleActionDirective(str, node as BaseDirective, element as Element);
handleActionDirective(node as BaseDirective, element as Element);
break;
case 'Transition':
handleTransitionDirective(str, node as BaseDirective, element as Element);
Expand Down
27 changes: 2 additions & 25 deletions packages/svelte2tsx/src/htmlxtojsx_v2/nodes/Action.ts
@@ -1,32 +1,9 @@
import MagicString from 'magic-string';
import { BaseDirective } from '../../interfaces';
import {
getDirectiveNameStartEndIdx,
rangeWithTrailingPropertyAccess,
TransformationArray
} from '../utils/node-utils';
import { Element } from './Element';

/**
* use:xxx={params} ---> __sveltets_2_ensureAction(xxx(svelte.mapElementTag('ParentNodeName'),(params)));
*/
export function handleActionDirective(
str: MagicString,
attr: BaseDirective,
element: Element
): void {
const transformations: TransformationArray = [
'__sveltets_2_ensureAction(',
getDirectiveNameStartEndIdx(str, attr),
`(${element.typingsNamespace}.mapElementTag('${element.tagName}')`
];
if (attr.expression) {
transformations.push(
',(',
rangeWithTrailingPropertyAccess(str.original, attr.expression),
')'
);
}
transformations.push('));');
element.appendToStartEnd(transformations);
export function handleActionDirective(attr: BaseDirective, element: Element): void {
element.addAction(attr);
}

0 comments on commit 9e1f5d3

Please sign in to comment.