Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
export let prop: any;
const defaultSlotProp = 1;
const namedSlotProp = true;
const spread = {a: true, b: ''};
</script>

{prop}
<slot {defaultSlotProp} />
<slot name="named" {namedSlotProp} />
<slot name="spread" {...spread} />
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,27 @@
"message": "Cannot find name 'namedSlotProp'.",
"code": 2304,
"tags": []
},
{
"range": {
"start": { "line": 13, "character": 39 },
"end": { "line": 13, "character": 40 }
},
"severity": 1,
"source": "ts",
"message": "Property 'd' does not exist on type '{ a: boolean; b: string; }'.",
"code": 2339,
"tags": []
},
{
"range": {
"start": { "line": 16, "character": 5 },
"end": { "line": 16, "character": 13 }
},
"severity": 1,
"source": "ts",
"message": "This condition will always return 'false' since the types 'boolean' and 'string' have no overlap.",
"code": 2367,
"tags": []
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,10 @@
{defaultSlotProp}
</p>
{namedSlotProp}
<p slot="spread" let:a let:b={c} let:d>
{a === true}
{c === ''}
{a === ''}
{d}
</p>
</Slots>
6 changes: 5 additions & 1 deletion packages/svelte2tsx/src/svelte2tsx/createRenderFunction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,11 @@ export function createRenderFunction({
Array.from(slots.entries())
.map(([name, attrs]) => {
const attrsAsString = Array.from(attrs.entries())
.map(([exportName, expr]) => `${exportName}:${expr}`)
.map(([exportName, expr]) =>
exportName.startsWith('__spread__')
? `...${expr}`
: `${exportName}:${expr}`
)
.join(', ');
return `'${name}': {${attrsAsString}}`;
})
Expand Down
19 changes: 19 additions & 0 deletions packages/svelte2tsx/src/svelte2tsx/nodes/slot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ export class SlotHandler {
return resolved;
}

/**
* Returns a string which expresses the given identifier unpacked to
* the top level in order to express the slot types correctly later on.
*
* Example: {#each items as item} ---> __sveltets_1_unwrapArr(items)
*/
private getResolveExpressionStr(
identifierDef: SvelteIdentifier,
scope: TemplateScope,
Expand Down Expand Up @@ -168,6 +174,10 @@ export class SlotHandler {
}));
}

/**
* Resolves the slot expression to a string that can be used
* in the props-object in the return type of the render function
*/
private resolveExpression(expression: Node, scope: TemplateScope) {
let resolved = this.resolvedExpression.get(expression);
if (resolved) {
Expand Down Expand Up @@ -234,6 +244,14 @@ export class SlotHandler {
if (attr.name == 'name') {
continue;
}

if (attr.type === 'Spread') {
const rawName = attr.expression.name;
const init = scope.getInit(rawName);
const name = init ? this.resolved.get(init) : rawName;
attributes.set(`__spread__${name}`, name);
}

if (!attr.value?.length) {
continue;
}
Expand Down Expand Up @@ -268,6 +286,7 @@ export class SlotHandler {
if (attrVal.type == 'MustacheTag') {
return this.resolveExpression(attrVal.expression, scope);
}

throw Error('Unknown attribute value type:' + attrVal.type);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<></>;function render() {
/*Ωignore_startΩ*/;const __sveltets_ensureSlot = __sveltets_1_createEnsureSlot();/*Ωignore_endΩ*/
<>{__sveltets_1_each(items, (item) => <>
<slot a={__sveltets_ensureSlot("default","a",item)} b={__sveltets_ensureSlot("default","b",{ item })} c={__sveltets_ensureSlot("default","c",{ item: 'abc' }.item)} d={__sveltets_ensureSlot("default","d",{ item: item })} e={__sveltets_ensureSlot("default","e",(__sveltets_1_store_get(item), $item))} f={__sveltets_ensureSlot("default","f",(__sveltets_1_store_get(item), $item))}>Hello</slot>
<slot a={__sveltets_ensureSlot("default","a",item)} b={__sveltets_ensureSlot("default","b",{ item })} c={__sveltets_ensureSlot("default","c",{ item: 'abc' }.item)} d={__sveltets_ensureSlot("default","d",{ item: item })} e={__sveltets_ensureSlot("default","e",(__sveltets_1_store_get(item), $item))} f={__sveltets_ensureSlot("default","f",(__sveltets_1_store_get(item), $item))} {...g} {...item}>Hello</slot>
</>)}</>
return { props: {}, slots: {'default': {a:__sveltets_1_unwrapArr(items), b:{ item:__sveltets_1_unwrapArr(items) }, c:{ item: 'abc' }.item, d:{ item: __sveltets_1_unwrapArr(items) }, e:$item, f:$item}}, getters: {}, events: {} }}
return { props: {}, slots: {'default': {a:__sveltets_1_unwrapArr(items), b:{ item:__sveltets_1_unwrapArr(items) }, c:{ item: 'abc' }.item, d:{ item: __sveltets_1_unwrapArr(items) }, e:$item, f:$item, ...g, ...__sveltets_1_unwrapArr(items)}}, getters: {}, events: {} }}

export default class Input__SvelteComponent_ extends __sveltets_1_createSvelte2TsxComponent(__sveltets_1_partial(__sveltets_1_with_any_event(render()))) {
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{#each items as item}
<slot a={item} b={{ item }} c={{ item: 'abc' }.item} d={{ item: item }} e={$item} f="{$item}">Hello</slot>
<slot a={item} b={{ item }} c={{ item: 'abc' }.item} d={{ item: item }} e={$item} f="{$item}" {...g} {...item}>Hello</slot>
{/each}